/*
 * The backend-independent part of the reference module.
 */

#define USE_THE_REPOSITORY_VARIABLE

#include "git-compat-util.h"
#include "abspath.h"
#include "advice.h"
#include "config.h"
#include "environment.h"
#include "strmap.h"
#include "gettext.h"
#include "hex.h"
#include "lockfile.h"
#include "iterator.h"
#include "refs.h"
#include "refs/refs-internal.h"
#include "hook.h"
#include "object-name.h"
#include "odb.h"
#include "object.h"
#include "path.h"
#include "submodule.h"
#include "worktree.h"
#include "strvec.h"
#include "repo-settings.h"
#include "setup.h"
#include "date.h"
#include "commit.h"
#include "wildmatch.h"
#include "ident.h"
#include "fsck.h"

/*
 * List of all available backends
 */
static const struct ref_storage_be *refs_backends[] = {
	[REF_STORAGE_FORMAT_FILES] = &refs_be_files,
	[REF_STORAGE_FORMAT_REFTABLE] = &refs_be_reftable,
};

static const struct ref_storage_be *find_ref_storage_backend(
	enum ref_storage_format ref_storage_format)
{
	if (ref_storage_format < ARRAY_SIZE(refs_backends))
		return refs_backends[ref_storage_format];
	return NULL;
}

enum ref_storage_format ref_storage_format_by_name(const char *name)
{
	for (unsigned int i = 0; i < ARRAY_SIZE(refs_backends); i++)
		if (refs_backends[i] && !strcmp(refs_backends[i]->name, name))
			return i;
	return REF_STORAGE_FORMAT_UNKNOWN;
}

const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format)
{
	const struct ref_storage_be *be = find_ref_storage_backend(ref_storage_format);
	if (!be)
		return "unknown";
	return be->name;
}

static const char *abort_by_ref_transaction_hook =
	N_("in '%s' phase, update aborted by the reference-transaction hook");

/*
 * How to handle various characters in refnames:
 * 0: An acceptable character for refs
 * 1: End-of-component
 * 2: ., look for a preceding . to reject .. in refs
 * 3: {, look for a preceding @ to reject @{ in refs
 * 4: A bad character: ASCII control characters, and
 *    ":", "?", "[", "\", "^", "~", SP, or TAB
 * 5: *, reject unless REFNAME_REFSPEC_PATTERN is set
 */
static unsigned char refname_disposition[256] = {
	1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
	4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
	4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 1,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
};

struct ref_namespace_info ref_namespace[] = {
	[NAMESPACE_HEAD] = {
		.ref = "HEAD",
		.decoration = DECORATION_REF_HEAD,
		.exact = 1,
	},
	[NAMESPACE_BRANCHES] = {
		.ref = "refs/heads/",
		.decoration = DECORATION_REF_LOCAL,
	},
	[NAMESPACE_TAGS] = {
		.ref = "refs/tags/",
		.decoration = DECORATION_REF_TAG,
	},
	[NAMESPACE_REMOTE_REFS] = {
		/*
		 * The default refspec for new remotes copies refs from
		 * refs/heads/ on the remote into refs/remotes/<remote>/.
		 * As such, "refs/remotes/" has special handling.
		 */
		.ref = "refs/remotes/",
		.decoration = DECORATION_REF_REMOTE,
	},
	[NAMESPACE_STASH] = {
		/*
		 * The single ref "refs/stash" stores the latest stash.
		 * Older stashes can be found in the reflog.
		 */
		.ref = "refs/stash",
		.exact = 1,
		.decoration = DECORATION_REF_STASH,
	},
	[NAMESPACE_REPLACE] = {
		/*
		 * This namespace allows Git to act as if one object ID
		 * points to the content of another. Unlike the other
		 * ref namespaces, this one can be changed by the
		 * GIT_REPLACE_REF_BASE environment variable. This
		 * .namespace value will be overwritten in setup_git_env().
		 */
		.ref = "refs/replace/",
		.decoration = DECORATION_GRAFTED,
	},
	[NAMESPACE_NOTES] = {
		/*
		 * The refs/notes/commit ref points to the tip of a
		 * parallel commit history that adds metadata to commits
		 * in the normal history. This ref can be overwritten
		 * by the core.notesRef config variable or the
		 * GIT_NOTES_REFS environment variable.
		 */
		.ref = "refs/notes/commit",
		.exact = 1,
	},
	[NAMESPACE_PREFETCH] = {
		/*
		 * Prefetch refs are written by the background 'fetch'
		 * maintenance task. It allows faster foreground fetches
		 * by advertising these previously-downloaded tips without
		 * updating refs/remotes/ without user intervention.
		 */
		.ref = "refs/prefetch/",
	},
	[NAMESPACE_REWRITTEN] = {
		/*
		 * Rewritten refs are used by the 'label' command in the
		 * sequencer. These are particularly useful during an
		 * interactive rebase that uses the 'merge' command.
		 */
		.ref = "refs/rewritten/",
	},
};

void update_ref_namespace(enum ref_namespace namespace, char *ref)
{
	struct ref_namespace_info *info = &ref_namespace[namespace];
	if (info->ref_updated)
		free((char *)info->ref);
	info->ref = ref;
	info->ref_updated = 1;
}

/*
 * Try to read one refname component from the front of refname.
 * Return the length of the component found, or -1 if the component is
 * not legal.  It is legal if it is something reasonable to have under
 * ".git/refs/"; We do not like it if:
 *
 * - it begins with ".", or
 * - it has double dots "..", or
 * - it has ASCII control characters, or
 * - it has ":", "?", "[", "\", "^", "~", SP, or TAB anywhere, or
 * - it has "*" anywhere unless REFNAME_REFSPEC_PATTERN is set, or
 * - it ends with a "/", or
 * - it ends with ".lock", or
 * - it contains a "@{" portion
 *
 * When sanitized is not NULL, instead of rejecting the input refname
 * as an error, try to come up with a usable replacement for the input
 * refname in it.
 */
static int check_refname_component(const char *refname, int *flags,
				   struct strbuf *sanitized)
{
	const char *cp;
	char last = '\0';
	size_t component_start = 0; /* garbage - not a reasonable initial value */

	if (sanitized)
		component_start = sanitized->len;

	for (cp = refname; ; cp++) {
		int ch = *cp & 255;
		unsigned char disp = refname_disposition[ch];

		if (sanitized && disp != 1)
			strbuf_addch(sanitized, ch);

		switch (disp) {
		case 1:
			goto out;
		case 2:
			if (last == '.') { /* Refname contains "..". */
				if (sanitized)
					/* collapse ".." to single "." */
					strbuf_setlen(sanitized, sanitized->len - 1);
				else
					return -1;
			}
			break;
		case 3:
			if (last == '@') { /* Refname contains "@{". */
				if (sanitized)
					sanitized->buf[sanitized->len-1] = '-';
				else
					return -1;
			}
			break;
		case 4:
			/* forbidden char */
			if (sanitized)
				sanitized->buf[sanitized->len-1] = '-';
			else
				return -1;
			break;
		case 5:
			if (!(*flags & REFNAME_REFSPEC_PATTERN)) {
				/* refspec can't be a pattern */
				if (sanitized)
					sanitized->buf[sanitized->len-1] = '-';
				else
					return -1;
			}

			/*
			 * Unset the pattern flag so that we only accept
			 * a single asterisk for one side of refspec.
			 */
			*flags &= ~ REFNAME_REFSPEC_PATTERN;
			break;
		}
		last = ch;
	}
out:
	if (cp == refname)
		return 0; /* Component has zero length. */

	if (refname[0] == '.') { /* Component starts with '.'. */
		if (sanitized)
			sanitized->buf[component_start] = '-';
		else
			return -1;
	}
	if (cp - refname >= LOCK_SUFFIX_LEN &&
	    !memcmp(cp - LOCK_SUFFIX_LEN, LOCK_SUFFIX, LOCK_SUFFIX_LEN)) {
		if (!sanitized)
			return -1;
		/* Refname ends with ".lock". */
		while (strbuf_strip_suffix(sanitized, LOCK_SUFFIX)) {
			/* try again in case we have .lock.lock */
		}
	}
	return cp - refname;
}

static int check_or_sanitize_refname(const char *refname, int flags,
				     struct strbuf *sanitized)
{
	int component_len, component_count = 0;

	if (!strcmp(refname, "@")) {
		/* Refname is a single character '@'. */
		if (sanitized)
			strbuf_addch(sanitized, '-');
		else
			return -1;
	}

	while (1) {
		if (sanitized && sanitized->len)
			strbuf_complete(sanitized, '/');

		/* We are at the start of a path component. */
		component_len = check_refname_component(refname, &flags,
							sanitized);
		if (sanitized && component_len == 0)
			; /* OK, omit empty component */
		else if (component_len <= 0)
			return -1;

		component_count++;
		if (refname[component_len] == '\0')
			break;
		/* Skip to next component. */
		refname += component_len + 1;
	}

	if (refname[component_len - 1] == '.') {
		/* Refname ends with '.'. */
		if (sanitized)
			; /* omit ending dot */
		else
			return -1;
	}
	if (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2)
		return -1; /* Refname has only one component. */
	return 0;
}

int check_refname_format(const char *refname, int flags)
{
	return check_or_sanitize_refname(refname, flags, NULL);
}

int refs_fsck_ref(struct ref_store *refs UNUSED, struct fsck_options *o,
		  struct fsck_ref_report *report,
		  const char *refname UNUSED, const struct object_id *oid)
{
	if (is_null_oid(oid))
		return fsck_report_ref(o, report, FSCK_MSG_BAD_REF_OID,
				       "points to invalid object ID '%s'",
				       oid_to_hex(oid));

	return 0;
}

int refs_fsck_symref(struct ref_store *refs UNUSED, struct fsck_options *o,
		     struct fsck_ref_report *report,
		     const char *refname, const char *target)
{
	const char *stripped_refname;

	parse_worktree_ref(refname, NULL, NULL, &stripped_refname);

	if (!strcmp(stripped_refname, "HEAD") &&
	    !starts_with(target, "refs/heads/") &&
	    fsck_report_ref(o, report, FSCK_MSG_BAD_HEAD_TARGET,
			    "HEAD points to non-branch '%s'", target))
		return -1;

	if (is_root_ref(target))
		return 0;

	if (check_refname_format(target, 0) &&
	    fsck_report_ref(o, report, FSCK_MSG_BAD_REFERENT_NAME,
			    "points to invalid refname '%s'", target))
		return -1;

	if (!starts_with(target, "refs/") &&
	    !starts_with(target, "worktrees/") &&
	    fsck_report_ref(o, report, FSCK_MSG_SYMREF_TARGET_IS_NOT_A_REF,
			    "points to non-ref target '%s'", target))
		return -1;

	return 0;
}

int refs_fsck(struct ref_store *refs, struct fsck_options *o,
	      struct worktree *wt)
{
	if (o->verbose)
		fprintf_ln(stderr, _("Checking references consistency"));

	return refs->be->fsck(refs, o, wt);
}

void sanitize_refname_component(const char *refname, struct strbuf *out)
{
	if (check_or_sanitize_refname(refname, REFNAME_ALLOW_ONELEVEL, out))
		BUG("sanitizing refname '%s' check returned error", refname);
}

int refname_is_safe(const char *refname)
{
	const char *rest;

	if (skip_prefix(refname, "refs/", &rest)) {
		char *buf;
		int result;
		size_t restlen = strlen(rest);

		/* rest must not be empty, or start or end with "/" */
		if (!restlen || *rest == '/' || rest[restlen - 1] == '/')
			return 0;

		/*
		 * Does the refname try to escape refs/?
		 * For example: refs/foo/../bar is safe but refs/foo/../../bar
		 * is not.
		 */
		buf = xmallocz(restlen);
		result = !normalize_path_copy(buf, rest) && !strcmp(buf, rest);
		free(buf);
		return result;
	}

	do {
		if (!isupper(*refname) && *refname != '_')
			return 0;
		refname++;
	} while (*refname);
	return 1;
}

/*
 * Return true if refname, which has the specified oid and flags, can
 * be resolved to an object in the database. If the referred-to object
 * does not exist, emit a warning and return false.
 */
int ref_resolves_to_object(const char *refname,
			   struct repository *repo,
			   const struct object_id *oid,
			   unsigned int flags)
{
	if (flags & REF_ISBROKEN)
		return 0;
	if (!odb_has_object(repo->objects, oid,
			    HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR)) {
		error(_("%s does not point to a valid object!"), refname);
		return 0;
	}
	return 1;
}

char *refs_resolve_refdup(struct ref_store *refs,
			  const char *refname, int resolve_flags,
			  struct object_id *oid, int *flags)
{
	const char *result;

	result = refs_resolve_ref_unsafe(refs, refname, resolve_flags,
					 oid, flags);
	return xstrdup_or_null(result);
}

/* The argument to for_each_filter_refs */
struct for_each_ref_filter {
	const char *pattern;
	size_t trim_prefix;
	refs_for_each_cb *fn;
	void *cb_data;
};

int refs_read_ref_full(struct ref_store *refs, const char *refname,
		       int resolve_flags, struct object_id *oid, int *flags)
{
	if (refs_resolve_ref_unsafe(refs, refname, resolve_flags,
				    oid, flags))
		return 0;
	return -1;
}

int refs_read_ref(struct ref_store *refs, const char *refname, struct object_id *oid)
{
	return refs_read_ref_full(refs, refname, RESOLVE_REF_READING, oid, NULL);
}

int refs_ref_exists(struct ref_store *refs, const char *refname)
{
	return !!refs_resolve_ref_unsafe(refs, refname, RESOLVE_REF_READING,
					 NULL, NULL);
}

static int for_each_filter_refs(const struct reference *ref, void *data)
{
	struct for_each_ref_filter *filter = data;

	if (wildmatch(filter->pattern, ref->name, 0))
		return 0;
	if (filter->trim_prefix) {
		struct reference skipped = *ref;
		if (strlen(skipped.name) <= filter->trim_prefix)
			BUG("attempt to trim too many characters");
		skipped.name += filter->trim_prefix;
		return filter->fn(&skipped, filter->cb_data);
	} else {
		return filter->fn(ref, filter->cb_data);
	}
}

struct warn_if_dangling_data {
	struct ref_store *refs;
	FILE *fp;
	const struct string_list *refnames;
	const char *indent;
	int dry_run;
};

static int warn_if_dangling_symref(const struct reference *ref, void *cb_data)
{
	struct warn_if_dangling_data *d = cb_data;
	const char *resolves_to, *msg;

	if (!(ref->flags & REF_ISSYMREF))
		return 0;

	resolves_to = refs_resolve_ref_unsafe(d->refs, ref->name, 0, NULL, NULL);
	if (!resolves_to
	    || !string_list_has_string(d->refnames, resolves_to)) {
		return 0;
	}

	msg = d->dry_run
		? _("%s%s will become dangling after %s is deleted\n")
		: _("%s%s has become dangling after %s was deleted\n");
	fprintf(d->fp, msg, d->indent, ref->name, resolves_to);
	return 0;
}

void refs_warn_dangling_symrefs(struct ref_store *refs, FILE *fp,
				const char *indent, int dry_run,
				const struct string_list *refnames)
{
	struct warn_if_dangling_data data = {
		.refs = refs,
		.fp = fp,
		.refnames = refnames,
		.indent = indent,
		.dry_run = dry_run,
	};
	struct refs_for_each_ref_options opts = {
		.flags = REFS_FOR_EACH_INCLUDE_BROKEN,
	};
	refs_for_each_ref_ext(refs, warn_if_dangling_symref, &data, &opts);
}

int refs_for_each_tag_ref(struct ref_store *refs, refs_for_each_cb cb, void *cb_data)
{
	struct refs_for_each_ref_options opts = {
		.prefix = "refs/tags/",
		.trim_prefix = strlen("refs/tags/"),
	};
	return refs_for_each_ref_ext(refs, cb, cb_data, &opts);
}

int refs_for_each_branch_ref(struct ref_store *refs, refs_for_each_cb cb, void *cb_data)
{
	struct refs_for_each_ref_options opts = {
		.prefix = "refs/heads/",
		.trim_prefix = strlen("refs/heads/"),
	};
	return refs_for_each_ref_ext(refs, cb, cb_data, &opts);
}

int refs_for_each_remote_ref(struct ref_store *refs, refs_for_each_cb cb, void *cb_data)
{
	struct refs_for_each_ref_options opts = {
		.prefix = "refs/remotes/",
		.trim_prefix = strlen("refs/remotes/"),
	};
	return refs_for_each_ref_ext(refs, cb, cb_data, &opts);
}

int refs_head_ref_namespaced(struct ref_store *refs, refs_for_each_cb fn, void *cb_data)
{
	struct strbuf buf = STRBUF_INIT;
	int ret = 0;
	struct object_id oid;
	int flag;

	strbuf_addf(&buf, "%sHEAD", get_git_namespace());
	if (!refs_read_ref_full(refs, buf.buf, RESOLVE_REF_READING, &oid, &flag)) {
		struct reference ref = {
			.name = buf.buf,
			.oid = &oid,
			.flags = flag,
		};

		ret = fn(&ref, cb_data);
	}
	strbuf_release(&buf);

	return ret;
}

void normalize_glob_ref(struct string_list_item *item, const char *prefix,
			const char *pattern)
{
	struct strbuf normalized_pattern = STRBUF_INIT;

	if (*pattern == '/')
		BUG("pattern must not start with '/'");

	if (prefix)
		strbuf_addstr(&normalized_pattern, prefix);
	else if (!starts_with(pattern, "refs/") &&
		   strcmp(pattern, "HEAD"))
		strbuf_addstr(&normalized_pattern, "refs/");
	/*
	 * NEEDSWORK: Special case other symrefs such as REBASE_HEAD,
	 * MERGE_HEAD, etc.
	 */

	strbuf_addstr(&normalized_pattern, pattern);
	strbuf_strip_suffix(&normalized_pattern, "/");

	item->string = strbuf_detach(&normalized_pattern, NULL);
	item->util = has_glob_specials(pattern) ? NULL : item->string;
	strbuf_release(&normalized_pattern);
}

const char *prettify_refname(const char *name)
{
	if (skip_prefix(name, "refs/heads/", &name) ||
	    skip_prefix(name, "refs/tags/", &name) ||
	    skip_prefix(name, "refs/remotes/", &name))
		; /* nothing */
	return name;
}

static const char *ref_rev_parse_rules[] = {
	"%.*s",
	"refs/%.*s",
	"refs/tags/%.*s",
	"refs/heads/%.*s",
	"refs/remotes/%.*s",
	"refs/remotes/%.*s/HEAD",
	NULL
};

#define NUM_REV_PARSE_RULES (ARRAY_SIZE(ref_rev_parse_rules) - 1)

/*
 * Is it possible that the caller meant full_name with abbrev_name?
 * If so return a non-zero value to signal "yes"; the magnitude of
 * the returned value gives the precedence used for disambiguation.
 *
 * If abbrev_name cannot mean full_name, return 0.
 */
int refname_match(const char *abbrev_name, const char *full_name)
{
	const char **p;
	const int abbrev_name_len = strlen(abbrev_name);
	const int num_rules = NUM_REV_PARSE_RULES;

	for (p = ref_rev_parse_rules; *p; p++)
		if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name)))
			return &ref_rev_parse_rules[num_rules] - p;

	return 0;
}

/*
 * Given a 'prefix' expand it by the rules in 'ref_rev_parse_rules' and add
 * the results to 'prefixes'
 */
void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
{
	const char **p;
	int len = strlen(prefix);

	for (p = ref_rev_parse_rules; *p; p++)
		strvec_pushf(prefixes, *p, len, prefix);
}

#ifndef WITH_BREAKING_CHANGES
static const char default_branch_name_advice[] = N_(
"Using '%s' as the name for the initial branch. This default branch name\n"
"will change to \"main\" in Git 3.0. To configure the initial branch name\n"
"to use in all of your new repositories, which will suppress this warning,\n"
"call:\n"
"\n"
"\tgit config --global init.defaultBranch <name>\n"
"\n"
"Names commonly chosen instead of 'master' are 'main', 'trunk' and\n"
"'development'. The just-created branch can be renamed via this command:\n"
"\n"
"\tgit branch -m <name>\n"
);
#else
static const char default_branch_name_advice[] = N_(
"Using '%s' as the name for the initial branch since Git 3.0.\n"
"If you expected Git to create 'master', the just-created\n"
"branch can be renamed via this command:\n"
"\n"
"\tgit branch -m master\n"
);
#endif /* WITH_BREAKING_CHANGES */

char *repo_default_branch_name(struct repository *r, int quiet)
{
	const char *config_key = "init.defaultbranch";
	const char *config_display_key = "init.defaultBranch";
	char *ret = NULL, *full_ref;
	const char *env = getenv("GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME");

	if (env && *env)
		ret = xstrdup(env);
	if (!ret && repo_config_get_string(r, config_key, &ret) < 0)
		die(_("could not retrieve `%s`"), config_display_key);

	if (!ret) {
#ifdef WITH_BREAKING_CHANGES
		ret = xstrdup("main");
#else
		ret = xstrdup("master");
#endif /* WITH_BREAKING_CHANGES */
		if (!quiet)
			advise_if_enabled(ADVICE_DEFAULT_BRANCH_NAME,
					  _(default_branch_name_advice), ret);
	}

	full_ref = xstrfmt("refs/heads/%s", ret);
	if (check_refname_format(full_ref, 0))
		die(_("invalid branch name: %s = %s"), config_display_key, ret);
	free(full_ref);

	return ret;
}

/*
 * *string and *len will only be substituted, and *string returned (for
 * later free()ing) if the string passed in is a magic short-hand form
 * to name a branch.
 */
static char *substitute_branch_name(struct repository *r,
				    const char **string, int *len,
				    int nonfatal_dangling_mark)
{
	struct strbuf buf = STRBUF_INIT;
	struct interpret_branch_name_options options = {
		.nonfatal_dangling_mark = nonfatal_dangling_mark
	};
	int ret = repo_interpret_branch_name(r, *string, *len, &buf, &options);

	if (ret == *len) {
		size_t size;
		*string = strbuf_detach(&buf, &size);
		*len = size;
		return (char *)*string;
	}

	return NULL;
}

void copy_branchname(struct strbuf *sb, const char *name,
		     enum interpret_branch_kind allowed)
{
	int len = strlen(name);
	struct interpret_branch_name_options options = {
		.allowed = allowed
	};
	int used = repo_interpret_branch_name(the_repository, name, len, sb,
					      &options);

	if (used < 0)
		used = 0;
	strbuf_add(sb, name + used, len - used);
}

int check_branch_ref(struct strbuf *sb, const char *name)
{
	if (startup_info->have_repository)
		copy_branchname(sb, name, INTERPRET_BRANCH_LOCAL);
	else
		strbuf_addstr(sb, name);

	/*
	 * This splice must be done even if we end up rejecting the
	 * name; builtin/branch.c::copy_or_rename_branch() still wants
	 * to see what the name expanded to so that "branch -m" can be
	 * used as a tool to correct earlier mistakes.
	 */
	strbuf_splice(sb, 0, 0, "refs/heads/", 11);

	if (*name == '-' ||
	    !strcmp(sb->buf, "refs/heads/HEAD"))
		return -1;

	return check_refname_format(sb->buf, 0);
}

int check_tag_ref(struct strbuf *sb, const char *name)
{
	if (name[0] == '-' || !strcmp(name, "HEAD"))
		return -1;

	strbuf_reset(sb);
	strbuf_addf(sb, "refs/tags/%s", name);

	return check_refname_format(sb->buf, 0);
}

int repo_dwim_ref(struct repository *r, const char *str, int len,
		  struct object_id *oid, char **ref, int nonfatal_dangling_mark)
{
	char *last_branch = substitute_branch_name(r, &str, &len,
						   nonfatal_dangling_mark);
	int   refs_found  = expand_ref(r, str, len, oid, ref);
	free(last_branch);
	return refs_found;
}

int expand_ref(struct repository *repo, const char *str, int len,
	       struct object_id *oid, char **ref)
{
	const char **p, *r;
	int refs_found = 0;
	struct strbuf fullref = STRBUF_INIT;

	*ref = NULL;
	for (p = ref_rev_parse_rules; *p; p++) {
		struct object_id oid_from_ref;
		struct object_id *this_result;
		int flag;
		struct ref_store *refs = get_main_ref_store(repo);

		this_result = refs_found ? &oid_from_ref : oid;
		strbuf_reset(&fullref);
		strbuf_addf(&fullref, *p, len, str);
		r = refs_resolve_ref_unsafe(refs, fullref.buf,
					    RESOLVE_REF_READING,
					    this_result, &flag);
		if (r) {
			if (!refs_found++)
				*ref = xstrdup(r);
			if (!repo_settings_get_warn_ambiguous_refs(repo))
				break;
		} else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) {
			warning(_("ignoring dangling symref %s"), fullref.buf);
		} else if ((flag & REF_ISBROKEN) && strchr(fullref.buf, '/')) {
			warning(_("ignoring broken ref %s"), fullref.buf);
		}
	}
	strbuf_release(&fullref);
	return refs_found;
}

int repo_dwim_log(struct repository *r, const char *str, int len,
		  struct object_id *oid, char **log)
{
	struct ref_store *refs = get_main_ref_store(r);
	char *last_branch = substitute_branch_name(r, &str, &len, 0);
	const char **p;
	int logs_found = 0;
	struct strbuf path = STRBUF_INIT;

	*log = NULL;
	for (p = ref_rev_parse_rules; *p; p++) {
		struct object_id hash;
		const char *ref, *it;

		strbuf_reset(&path);
		strbuf_addf(&path, *p, len, str);
		ref = refs_resolve_ref_unsafe(refs, path.buf,
					      RESOLVE_REF_READING,
					      oid ? &hash : NULL, NULL);
		if (!ref)
			continue;
		if (refs_reflog_exists(refs, path.buf))
			it = path.buf;
		else if (strcmp(ref, path.buf) &&
			 refs_reflog_exists(refs, ref))
			it = ref;
		else
			continue;
		if (!logs_found++) {
			*log = xstrdup(it);
			if (oid)
				oidcpy(oid, &hash);
		}
		if (!repo_settings_get_warn_ambiguous_refs(r))
			break;
	}
	strbuf_release(&path);
	free(last_branch);
	return logs_found;
}

int is_per_worktree_ref(const char *refname)
{
	return starts_with(refname, "refs/worktree/") ||
	       starts_with(refname, "refs/bisect/") ||
	       starts_with(refname, "refs/rewritten/");
}

int is_pseudo_ref(const char *refname)
{
	static const char * const pseudo_refs[] = {
		"FETCH_HEAD",
		"MERGE_HEAD",
	};
	size_t i;

	for (i = 0; i < ARRAY_SIZE(pseudo_refs); i++)
		if (!strcmp(refname, pseudo_refs[i]))
			return 1;

	return 0;
}

static int is_root_ref_syntax(const char *refname)
{
	const char *c;

	for (c = refname; *c; c++) {
		if (!isupper(*c) && *c != '-' && *c != '_')
			return 0;
	}

	return 1;
}

int is_root_ref(const char *refname)
{
	static const char *const irregular_root_refs[] = {
		"HEAD",
		"AUTO_MERGE",
		"BISECT_EXPECTED_REV",
		"NOTES_MERGE_PARTIAL",
		"NOTES_MERGE_REF",
		"MERGE_AUTOSTASH",
	};
	size_t i;

	if (!is_root_ref_syntax(refname) ||
	    is_pseudo_ref(refname))
		return 0;

	if (ends_with(refname, "_HEAD"))
		return 1;

	for (i = 0; i < ARRAY_SIZE(irregular_root_refs); i++)
		if (!strcmp(refname, irregular_root_refs[i]))
			return 1;

	return 0;
}

static int is_current_worktree_ref(const char *ref) {
	return is_root_ref_syntax(ref) || is_per_worktree_ref(ref);
}

enum ref_worktree_type parse_worktree_ref(const char *maybe_worktree_ref,
					  const char **worktree_name, int *worktree_name_length,
					  const char **bare_refname)
{
	const char *name_dummy;
	int name_length_dummy;
	const char *ref_dummy;

	if (!worktree_name)
		worktree_name = &name_dummy;
	if (!worktree_name_length)
		worktree_name_length = &name_length_dummy;
	if (!bare_refname)
		bare_refname = &ref_dummy;

	if (skip_prefix(maybe_worktree_ref, "worktrees/", bare_refname)) {
		const char *slash = strchr(*bare_refname, '/');

		*worktree_name = *bare_refname;
		if (!slash) {
			*worktree_name_length = strlen(*worktree_name);

			/* This is an error condition, and the caller tell because the bare_refname is "" */
			*bare_refname = *worktree_name + *worktree_name_length;
			return REF_WORKTREE_OTHER;
		}

		*worktree_name_length = slash - *bare_refname;
		*bare_refname = slash + 1;

		if (is_current_worktree_ref(*bare_refname))
			return REF_WORKTREE_OTHER;
	}

	*worktree_name = NULL;
	*worktree_name_length = 0;

	if (skip_prefix(maybe_worktree_ref, "main-worktree/", bare_refname)
	    && is_current_worktree_ref(*bare_refname))
		return REF_WORKTREE_MAIN;

	*bare_refname = maybe_worktree_ref;
	if (is_current_worktree_ref(maybe_worktree_ref))
		return REF_WORKTREE_CURRENT;

	return REF_WORKTREE_SHARED;
}

long get_files_ref_lock_timeout_ms(void)
{
	static int configured = 0;

	/* The default timeout is 100 ms: */
	static int timeout_ms = 100;

	if (!configured) {
		repo_config_get_int(the_repository, "core.filesreflocktimeout", &timeout_ms);
		configured = 1;
	}

	return timeout_ms;
}

int refs_delete_ref(struct ref_store *refs, const char *msg,
		    const char *refname,
		    const struct object_id *old_oid,
		    unsigned int flags)
{
	struct ref_transaction *transaction;
	struct strbuf err = STRBUF_INIT;

	transaction = ref_store_transaction_begin(refs, 0, &err);
	if (!transaction ||
	    ref_transaction_delete(transaction, refname, old_oid,
				   NULL, flags, msg, &err) ||
	    ref_transaction_commit(transaction, &err)) {
		error("%s", err.buf);
		ref_transaction_free(transaction);
		strbuf_release(&err);
		return 1;
	}
	ref_transaction_free(transaction);
	strbuf_release(&err);
	return 0;
}

static void copy_reflog_msg(struct strbuf *sb, const char *msg)
{
	char c;
	int wasspace = 1;

	while ((c = *msg++)) {
		if (wasspace && isspace(c))
			continue;
		wasspace = isspace(c);
		if (wasspace)
			c = ' ';
		strbuf_addch(sb, c);
	}
	strbuf_rtrim(sb);
}

static char *normalize_reflog_message(const char *msg)
{
	struct strbuf sb = STRBUF_INIT;

	if (msg && *msg)
		copy_reflog_msg(&sb, msg);
	return strbuf_detach(&sb, NULL);
}

int should_autocreate_reflog(enum log_refs_config log_all_ref_updates,
			     const char *refname)
{
	switch (log_all_ref_updates) {
	case LOG_REFS_ALWAYS:
		return 1;
	case LOG_REFS_NORMAL:
		return starts_with(refname, "refs/heads/") ||
			starts_with(refname, "refs/remotes/") ||
			starts_with(refname, "refs/notes/") ||
			!strcmp(refname, "HEAD");
	default:
		return 0;
	}
}

int is_branch(const char *refname)
{
	return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/");
}

struct read_ref_at_cb {
	timestamp_t at_time;
	int cnt;
	int reccnt;
	struct object_id *oid;
	int found_it;

	struct object_id ooid;
	struct object_id noid;
	int tz;
	timestamp_t date;
	char **msg;
	timestamp_t *cutoff_time;
	int *cutoff_tz;
	int *cutoff_cnt;
};

static void set_read_ref_cutoffs(struct read_ref_at_cb *cb,
		timestamp_t timestamp, int tz, const char *message)
{
	if (cb->msg)
		*cb->msg = xstrdup(message);
	if (cb->cutoff_time)
		*cb->cutoff_time = timestamp;
	if (cb->cutoff_tz)
		*cb->cutoff_tz = tz;
	if (cb->cutoff_cnt)
		*cb->cutoff_cnt = cb->reccnt;
}

static int read_ref_at_ent(const char *refname,
			   struct object_id *ooid, struct object_id *noid,
			   const char *email UNUSED,
			   timestamp_t timestamp, int tz,
			   const char *message, void *cb_data)
{
	struct read_ref_at_cb *cb = cb_data;

	cb->tz = tz;
	cb->date = timestamp;

	if (timestamp <= cb->at_time || cb->cnt == 0) {
		set_read_ref_cutoffs(cb, timestamp, tz, message);
		/*
		 * we have not yet updated cb->[n|o]oid so they still
		 * hold the values for the previous record.
		 */
		if (!is_null_oid(&cb->ooid)) {
			oidcpy(cb->oid, noid);
			if (!oideq(&cb->ooid, noid))
				warning(_("log for ref %s has gap after %s"),
					refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822)));
		}
		else if (cb->date == cb->at_time)
			oidcpy(cb->oid, noid);
		else if (!oideq(noid, cb->oid))
			warning(_("log for ref %s unexpectedly ended on %s"),
				refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822)));
		cb->reccnt++;
		oidcpy(&cb->ooid, ooid);
		oidcpy(&cb->noid, noid);
		cb->found_it = 1;
		return 1;
	}
	cb->reccnt++;
	oidcpy(&cb->ooid, ooid);
	oidcpy(&cb->noid, noid);
	if (cb->cnt > 0)
		cb->cnt--;
	return 0;
}

static int read_ref_at_ent_oldest(const char *refname UNUSED,
				  struct object_id *ooid, struct object_id *noid,
				  const char *email UNUSED,
				  timestamp_t timestamp, int tz,
				  const char *message, void *cb_data)
{
	struct read_ref_at_cb *cb = cb_data;

	set_read_ref_cutoffs(cb, timestamp, tz, message);
	oidcpy(cb->oid, ooid);
	if (cb->at_time && is_null_oid(cb->oid))
		oidcpy(cb->oid, noid);
	/* We just want the first entry */
	return 1;
}

int read_ref_at(struct ref_store *refs, const char *refname,
		unsigned int flags, timestamp_t at_time, int cnt,
		struct object_id *oid, char **msg,
		timestamp_t *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
{
	struct read_ref_at_cb cb;

	memset(&cb, 0, sizeof(cb));
	cb.at_time = at_time;
	cb.cnt = cnt;
	cb.msg = msg;
	cb.cutoff_time = cutoff_time;
	cb.cutoff_tz = cutoff_tz;
	cb.cutoff_cnt = cutoff_cnt;
	cb.oid = oid;

	refs_for_each_reflog_ent_reverse(refs, refname, read_ref_at_ent, &cb);

	if (!cb.reccnt) {
		if (cnt == 0) {
			/*
			 * The caller asked for ref@{0}, and we had no entries.
			 * It's a bit subtle, but in practice all callers have
			 * prepped the "oid" field with the current value of
			 * the ref, which is the most reasonable fallback.
			 *
			 * We'll put dummy values into the out-parameters (so
			 * they're not just uninitialized garbage), and the
			 * caller can take our return value as a hint that
			 * we did not find any such reflog.
			 */
			set_read_ref_cutoffs(&cb, 0, 0, "empty reflog");
			return 1;
		}
		if (flags & GET_OID_QUIETLY)
			exit(128);
		else
			die(_("log for %s is empty"), refname);
	}
	if (cb.found_it)
		return 0;

	refs_for_each_reflog_ent(refs, refname, read_ref_at_ent_oldest, &cb);

	return 1;
}

struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs,
						    unsigned int flags,
						    struct strbuf *err)
{
	struct ref_transaction *tr;
	assert(err);

	CALLOC_ARRAY(tr, 1);
	tr->ref_store = refs;
	tr->flags = flags;
	string_list_init_dup(&tr->refnames);

	if (flags & REF_TRANSACTION_ALLOW_FAILURE)
		CALLOC_ARRAY(tr->rejections, 1);

	return tr;
}

void ref_transaction_free(struct ref_transaction *transaction)
{
	size_t i;

	if (!transaction)
		return;

	switch (transaction->state) {
	case REF_TRANSACTION_OPEN:
	case REF_TRANSACTION_CLOSED:
		/* OK */
		break;
	case REF_TRANSACTION_PREPARED:
		BUG("free called on a prepared reference transaction");
		break;
	default:
		BUG("unexpected reference transaction state");
		break;
	}

	for (i = 0; i < transaction->nr; i++) {
		free(transaction->updates[i]->msg);
		free(transaction->updates[i]->committer_info);
		free((char *)transaction->updates[i]->new_target);
		free((char *)transaction->updates[i]->old_target);
		free((char *)transaction->updates[i]->rejection_details);
		free(transaction->updates[i]);
	}

	if (transaction->rejections)
		free(transaction->rejections->update_indices);
	free(transaction->rejections);

	string_list_clear(&transaction->refnames, 0);
	free(transaction->updates);
	free(transaction);
}

int ref_transaction_maybe_set_rejected(struct ref_transaction *transaction,
				       size_t update_idx,
				       enum ref_transaction_error err,
				       struct strbuf *details)
{
	if (update_idx >= transaction->nr)
		BUG("trying to set rejection on invalid update index");

	if (!(transaction->flags & REF_TRANSACTION_ALLOW_FAILURE))
		return 0;

	if (!transaction->rejections)
		BUG("transaction not initialized with failure support");

	/*
	 * Don't accept generic errors, since these errors are not user
	 * input related.
	 */
	if (err == REF_TRANSACTION_ERROR_GENERIC)
		return 0;

	/*
	 * Rejected refnames shouldn't be considered in the availability
	 * checks, so remove them from the list.
	 */
	string_list_remove(&transaction->refnames,
			   transaction->updates[update_idx]->refname, 0);

	transaction->updates[update_idx]->rejection_err = err;
	transaction->updates[update_idx]->rejection_details = strbuf_detach(details, NULL);
	ALLOC_GROW(transaction->rejections->update_indices,
		   transaction->rejections->nr + 1,
		   transaction->rejections->alloc);
	transaction->rejections->update_indices[transaction->rejections->nr++] = update_idx;

	return 1;
}

struct ref_update *ref_transaction_add_update(
		struct ref_transaction *transaction,
		const char *refname, unsigned int flags,
		const struct object_id *new_oid,
		const struct object_id *old_oid,
		const char *new_target, const char *old_target,
		const char *committer_info,
		const char *msg)
{
	struct string_list_item *item;
	struct ref_update *update;

	if (transaction->state != REF_TRANSACTION_OPEN)
		BUG("update called for transaction that is not open");

	if (old_oid && old_target)
		BUG("only one of old_oid and old_target should be non NULL");
	if (new_oid && new_target)
		BUG("only one of new_oid and new_target should be non NULL");

	FLEX_ALLOC_STR(update, refname, refname);
	ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
	transaction->updates[transaction->nr++] = update;

	update->flags = flags;
	update->rejection_err = 0;

	update->new_target = xstrdup_or_null(new_target);
	update->old_target = xstrdup_or_null(old_target);
	if ((flags & REF_HAVE_NEW) && new_oid)
		oidcpy(&update->new_oid, new_oid);
	if ((flags & REF_HAVE_OLD) && old_oid)
		oidcpy(&update->old_oid, old_oid);
	if (!(flags & REF_SKIP_CREATE_REFLOG)) {
		update->committer_info = xstrdup_or_null(committer_info);
		update->msg = normalize_reflog_message(msg);
	}

	/*
	 * This list is generally used by the backends to avoid duplicates.
	 * But we do support multiple log updates for a given refname within
	 * a single transaction.
	 */
	if (!(update->flags & REF_LOG_ONLY)) {
		item = string_list_append(&transaction->refnames, refname);
		item->util = update;
	}

	return update;
}

static int transaction_refname_valid(const char *refname,
				     const struct object_id *new_oid,
				     unsigned int flags, struct strbuf *err)
{
	if (flags & REF_SKIP_REFNAME_VERIFICATION)
		return 1;

	if (is_pseudo_ref(refname)) {
		const char *refusal_msg;
		if (flags & REF_LOG_ONLY)
			refusal_msg = _("refusing to update reflog for pseudoref '%s'");
		else
			refusal_msg = _("refusing to update pseudoref '%s'");
		strbuf_addf(err, refusal_msg, refname);
		return 0;
	} else if ((new_oid && !is_null_oid(new_oid)) ?
		 check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
		 !refname_is_safe(refname)) {
		const char *refusal_msg;
		if (flags & REF_LOG_ONLY)
			refusal_msg = _("refusing to update reflog with bad name '%s'");
		else
			refusal_msg = _("refusing to update ref with bad name '%s'");
		strbuf_addf(err, refusal_msg, refname);
		return 0;
	}

	return 1;
}

int ref_transaction_update(struct ref_transaction *transaction,
			   const char *refname,
			   const struct object_id *new_oid,
			   const struct object_id *old_oid,
			   const char *new_target,
			   const char *old_target,
			   unsigned int flags, const char *msg,
			   struct strbuf *err)
{
	assert(err);

	if ((flags & REF_FORCE_CREATE_REFLOG) &&
	    (flags & REF_SKIP_CREATE_REFLOG)) {
		strbuf_addstr(err, _("refusing to force and skip creation of reflog"));
		return -1;
	}

	if (!transaction_refname_valid(refname, new_oid, flags, err))
		return -1;

	if (flags & ~REF_TRANSACTION_UPDATE_ALLOWED_FLAGS)
		BUG("illegal flags 0x%x passed to ref_transaction_update()", flags);

	/*
	 * Clear flags outside the allowed set; this should be a noop because
	 * of the BUG() check above, but it works around a -Wnonnull warning
	 * with some versions of "gcc -O3".
	 */
	flags &= REF_TRANSACTION_UPDATE_ALLOWED_FLAGS;

	flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0);
	flags |= (new_target ? REF_HAVE_NEW : 0) | (old_target ? REF_HAVE_OLD : 0);

	ref_transaction_add_update(transaction, refname, flags,
				   new_oid, old_oid, new_target,
				   old_target, NULL, msg);

	return 0;
}

int ref_transaction_update_reflog(struct ref_transaction *transaction,
				  const char *refname,
				  const struct object_id *new_oid,
				  const struct object_id *old_oid,
				  const char *committer_info,
				  const char *msg,
				  uint64_t index,
				  struct strbuf *err)
{
	struct ref_update *update;
	unsigned int flags;

	assert(err);

	flags = REF_HAVE_OLD | REF_HAVE_NEW | REF_LOG_ONLY | REF_FORCE_CREATE_REFLOG | REF_NO_DEREF |
		REF_LOG_USE_PROVIDED_OIDS;

	if (!transaction_refname_valid(refname, new_oid, flags, err))
		return -1;

	update = ref_transaction_add_update(transaction, refname, flags,
					    new_oid, old_oid, NULL, NULL,
					    committer_info, msg);
	update->index = index;

	/*
	 * Reference backends may need to know the max index to optimize
	 * their writes. So we store the max_index on the transaction level.
	 */
	if (index > transaction->max_index)
		transaction->max_index = index;

	return 0;
}

int ref_transaction_create(struct ref_transaction *transaction,
			   const char *refname,
			   const struct object_id *new_oid,
			   const char *new_target,
			   unsigned int flags, const char *msg,
			   struct strbuf *err)
{
	if (new_oid && new_target)
		BUG("create called with both new_oid and new_target set");
	if ((!new_oid || is_null_oid(new_oid)) && !new_target) {
		strbuf_addf(err, "'%s' has neither a valid OID nor a target", refname);
		return 1;
	}
	return ref_transaction_update(transaction, refname, new_oid,
				      null_oid(the_hash_algo), new_target, NULL, flags,
				      msg, err);
}

int ref_transaction_delete(struct ref_transaction *transaction,
			   const char *refname,
			   const struct object_id *old_oid,
			   const char *old_target,
			   unsigned int flags,
			   const char *msg,
			   struct strbuf *err)
{
	if (old_oid && is_null_oid(old_oid))
		BUG("delete called with old_oid set to zeros");
	if (old_oid && old_target)
		BUG("delete called with both old_oid and old_target set");
	if (old_target && !(flags & REF_NO_DEREF))
		BUG("delete cannot operate on symrefs with deref mode");
	return ref_transaction_update(transaction, refname,
				      null_oid(the_hash_algo), old_oid,
				      NULL, old_target, flags,
				      msg, err);
}

int ref_transaction_verify(struct ref_transaction *transaction,
			   const char *refname,
			   const struct object_id *old_oid,
			   const char *old_target,
			   unsigned int flags,
			   struct strbuf *err)
{
	if (!old_target && !old_oid)
		BUG("verify called with old_oid and old_target set to NULL");
	if (old_oid && old_target)
		BUG("verify called with both old_oid and old_target set");
	if (old_target && !(flags & REF_NO_DEREF))
		BUG("verify cannot operate on symrefs with deref mode");
	return ref_transaction_update(transaction, refname,
				      NULL, old_oid,
				      NULL, old_target,
				      flags, NULL, err);
}

int refs_update_ref(struct ref_store *refs, const char *msg,
		    const char *refname, const struct object_id *new_oid,
		    const struct object_id *old_oid, unsigned int flags,
		    enum action_on_err onerr)
{
	struct ref_transaction *t = NULL;
	struct strbuf err = STRBUF_INIT;
	int ret = 0;

	t = ref_store_transaction_begin(refs, 0, &err);
	if (!t ||
	    ref_transaction_update(t, refname, new_oid, old_oid, NULL, NULL,
				   flags, msg, &err) ||
	    ref_transaction_commit(t, &err)) {
		ret = 1;
		ref_transaction_free(t);
	}
	if (ret) {
		const char *str = _("update_ref failed for ref '%s': %s");

		switch (onerr) {
		case UPDATE_REFS_MSG_ON_ERR:
			error(str, refname, err.buf);
			break;
		case UPDATE_REFS_DIE_ON_ERR:
			die(str, refname, err.buf);
			break;
		case UPDATE_REFS_QUIET_ON_ERR:
			break;
		}
		strbuf_release(&err);
		return 1;
	}
	strbuf_release(&err);
	if (t)
		ref_transaction_free(t);
	return 0;
}

/*
 * Check that the string refname matches a rule of the form
 * "{prefix}%.*s{suffix}". So "foo/bar/baz" would match the rule
 * "foo/%.*s/baz", and return the string "bar".
 */
static const char *match_parse_rule(const char *refname, const char *rule,
				    size_t *len)
{
	/*
	 * Check that rule matches refname up to the first percent in the rule.
	 * We can bail immediately if not, but otherwise we leave "rule" at the
	 * %-placeholder, and "refname" at the start of the potential matched
	 * name.
	 */
	while (*rule != '%') {
		if (!*rule)
			BUG("rev-parse rule did not have percent");
		if (*refname++ != *rule++)
			return NULL;
	}

	/*
	 * Check that our "%" is the expected placeholder. This assumes there
	 * are no other percents (placeholder or quoted) in the string, but
	 * that is sufficient for our rev-parse rules.
	 */
	if (!skip_prefix(rule, "%.*s", &rule))
		return NULL;

	/*
	 * And now check that our suffix (if any) matches.
	 */
	if (!strip_suffix(refname, rule, len))
		return NULL;

	return refname; /* len set by strip_suffix() */
}

char *refs_shorten_unambiguous_ref(struct ref_store *refs,
				   const char *refname, int strict)
{
	int i;
	struct strbuf resolved_buf = STRBUF_INIT;

	/* skip first rule, it will always match */
	for (i = NUM_REV_PARSE_RULES - 1; i > 0 ; --i) {
		int j;
		int rules_to_fail = i;
		const char *short_name;
		size_t short_name_len;

		short_name = match_parse_rule(refname, ref_rev_parse_rules[i],
					      &short_name_len);
		if (!short_name)
			continue;

		/*
		 * in strict mode, all (except the matched one) rules
		 * must fail to resolve to a valid non-ambiguous ref
		 */
		if (strict)
			rules_to_fail = NUM_REV_PARSE_RULES;

		/*
		 * check if the short name resolves to a valid ref,
		 * but use only rules prior to the matched one
		 */
		for (j = 0; j < rules_to_fail; j++) {
			const char *rule = ref_rev_parse_rules[j];

			/* skip matched rule */
			if (i == j)
				continue;

			/*
			 * the short name is ambiguous, if it resolves
			 * (with this previous rule) to a valid ref
			 * read_ref() returns 0 on success
			 */
			strbuf_reset(&resolved_buf);
			strbuf_addf(&resolved_buf, rule,
				    cast_size_t_to_int(short_name_len),
				    short_name);
			if (refs_ref_exists(refs, resolved_buf.buf))
				break;
		}

		/*
		 * short name is non-ambiguous if all previous rules
		 * haven't resolved to a valid ref
		 */
		if (j == rules_to_fail) {
			strbuf_release(&resolved_buf);
			return xmemdupz(short_name, short_name_len);
		}
	}

	strbuf_release(&resolved_buf);
	return xstrdup(refname);
}

int parse_hide_refs_config(const char *var, const char *value, const char *section,
			   struct strvec *hide_refs)
{
	const char *key;
	if (!strcmp("transfer.hiderefs", var) ||
	    (!parse_config_key(var, section, NULL, NULL, &key) &&
	     !strcmp(key, "hiderefs"))) {
		char *ref;
		int len;

		if (!value)
			return config_error_nonbool(var);

		/* drop const to remove trailing '/' characters */
		ref = (char *)strvec_push(hide_refs, value);
		len = strlen(ref);
		while (len && ref[len - 1] == '/')
			ref[--len] = '\0';
	}
	return 0;
}

int ref_is_hidden(const char *refname, const char *refname_full,
		  const struct strvec *hide_refs)
{
	int i;

	for (i = hide_refs->nr - 1; i >= 0; i--) {
		const char *match = hide_refs->v[i];
		const char *subject;
		int neg = 0;
		const char *p;

		if (*match == '!') {
			neg = 1;
			match++;
		}

		if (*match == '^') {
			subject = refname_full;
			match++;
		} else {
			subject = refname;
		}

		/* refname can be NULL when namespaces are used. */
		if (subject &&
		    skip_prefix(subject, match, &p) &&
		    (!*p || *p == '/'))
			return !neg;
	}
	return 0;
}

const char **hidden_refs_to_excludes(const struct strvec *hide_refs)
{
	const char **pattern;
	for (pattern = hide_refs->v; *pattern; pattern++) {
		/*
		 * We can't feed any excludes from hidden refs config
		 * sections, since later rules may override previous
		 * ones. For example, with rules "refs/foo" and
		 * "!refs/foo/bar", we should show "refs/foo/bar" (and
		 * everything underneath it), but the earlier exclusion
		 * would cause us to skip all of "refs/foo".  We
		 * likewise don't implement the namespace stripping
		 * required for '^' rules.
		 *
		 * Both are possible to do, but complicated, so avoid
		 * populating the jump list at all if we see either of
		 * these patterns.
		 */
		if (**pattern == '!' || **pattern == '^')
			return NULL;
	}
	return hide_refs->v;
}

const char **get_namespaced_exclude_patterns(const char **exclude_patterns,
					     const char *namespace,
					     struct strvec *out)
{
	if (!namespace || !*namespace || !exclude_patterns || !*exclude_patterns)
		return exclude_patterns;

	for (size_t i = 0; exclude_patterns[i]; i++)
		strvec_pushf(out, "%s%s", namespace, exclude_patterns[i]);

	return out->v;
}

const char *find_descendant_ref(const char *dirname,
				const struct string_list *extras,
				const struct string_list *skip)
{
	if (!extras)
		return NULL;

	/*
	 * Look at the place where dirname would be inserted into
	 * extras. If there is an entry at that position that starts
	 * with dirname (remember, dirname includes the trailing
	 * slash) and is not in skip, then we have a conflict.
	 */
	for (size_t pos = string_list_find_insert_index(extras, dirname, NULL);
	     pos < extras->nr; pos++) {
		const char *extra_refname = extras->items[pos].string;

		if (!starts_with(extra_refname, dirname))
			break;

		if (!skip || !string_list_has_string(skip, extra_refname))
			return extra_refname;
	}
	return NULL;
}

int refs_head_ref(struct ref_store *refs, refs_for_each_cb fn, void *cb_data)
{
	struct object_id oid;
	int flag;

	if (refs_resolve_ref_unsafe(refs, "HEAD", RESOLVE_REF_READING,
				    &oid, &flag)) {
		struct reference ref = {
			.name = "HEAD",
			.oid = &oid,
			.flags = flag,
		};

		return fn(&ref, cb_data);
	}

	return 0;
}

struct ref_iterator *refs_ref_iterator_begin(
		struct ref_store *refs,
		const char *prefix,
		const char **exclude_patterns,
		int trim,
		enum refs_for_each_flag flags)
{
	struct ref_iterator *iter;
	struct strvec normalized_exclude_patterns = STRVEC_INIT;

	if (exclude_patterns) {
		for (size_t i = 0; exclude_patterns[i]; i++) {
			const char *pattern = exclude_patterns[i];
			size_t len = strlen(pattern);
			if (!len)
				continue;

			if (pattern[len - 1] == '/')
				strvec_push(&normalized_exclude_patterns, pattern);
			else
				strvec_pushf(&normalized_exclude_patterns, "%s/",
					     pattern);
		}

		exclude_patterns = normalized_exclude_patterns.v;
	}

	if (!(flags & REFS_FOR_EACH_INCLUDE_BROKEN)) {
		static int ref_paranoia = -1;

		if (ref_paranoia < 0)
			ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 1);
		if (ref_paranoia) {
			flags |= REFS_FOR_EACH_INCLUDE_BROKEN;
			flags |= REFS_FOR_EACH_OMIT_DANGLING_SYMREFS;
		}
	}

	iter = refs->be->iterator_begin(refs, prefix, exclude_patterns, flags);
	/*
	 * `iterator_begin()` already takes care of prefix, but we
	 * might need to do some trimming:
	 */
	if (trim)
		iter = prefix_ref_iterator_begin(iter, "", trim);

	strvec_clear(&normalized_exclude_patterns);

	return iter;
}

int refs_for_each_ref_ext(struct ref_store *refs,
			  refs_for_each_cb cb, void *cb_data,
			  const struct refs_for_each_ref_options *opts)
{
	struct strvec namespaced_exclude_patterns = STRVEC_INIT;
	struct strbuf namespaced_prefix = STRBUF_INIT;
	struct strbuf real_pattern = STRBUF_INIT;
	struct for_each_ref_filter filter;
	struct ref_iterator *iter;
	size_t trim_prefix = opts->trim_prefix;
	const char **exclude_patterns;
	const char *prefix;
	int ret;

	if (!refs)
		BUG("no ref store passed");

	if (opts->trim_prefix) {
		size_t prefix_len;

		if (!opts->prefix)
			BUG("trimming only allowed with a prefix");

		prefix_len = strlen(opts->prefix);
		if (prefix_len == opts->trim_prefix && opts->prefix[prefix_len - 1] != '/')
			BUG("ref pattern must end in a trailing slash when trimming");
	}

	if (opts->pattern) {
		if (!opts->prefix && !starts_with(opts->pattern, "refs/"))
			strbuf_addstr(&real_pattern, "refs/");
		else if (opts->prefix)
			strbuf_addstr(&real_pattern, opts->prefix);
		strbuf_addstr(&real_pattern, opts->pattern);

		if (!has_glob_specials(opts->pattern)) {
			/* Append implied '/' '*' if not present. */
			strbuf_complete(&real_pattern, '/');
			/* No need to check for '*', there is none. */
			strbuf_addch(&real_pattern, '*');
		}

		filter.pattern = real_pattern.buf;
		filter.trim_prefix = opts->trim_prefix;
		filter.fn = cb;
		filter.cb_data = cb_data;

		/*
		 * We need to trim the prefix in the callback function as the
		 * pattern is expected to match on the full refname.
		 */
		trim_prefix = 0;

		cb = for_each_filter_refs;
		cb_data = &filter;
	}

	if (opts->namespace) {
		strbuf_addstr(&namespaced_prefix, opts->namespace);
		if (opts->prefix)
			strbuf_addstr(&namespaced_prefix, opts->prefix);
		else
			strbuf_addstr(&namespaced_prefix, "refs/");

		prefix = namespaced_prefix.buf;
		exclude_patterns = get_namespaced_exclude_patterns(opts->exclude_patterns,
								   opts->namespace,
								   &namespaced_exclude_patterns);
	} else {
		prefix = opts->prefix ? opts->prefix : "";
		exclude_patterns = opts->exclude_patterns;
	}

	iter = refs_ref_iterator_begin(refs, prefix, exclude_patterns,
				       trim_prefix, opts->flags);

	ret = do_for_each_ref_iterator(iter, cb, cb_data);

	strvec_clear(&namespaced_exclude_patterns);
	strbuf_release(&namespaced_prefix);
	strbuf_release(&real_pattern);
	return ret;
}

int refs_for_each_ref(struct ref_store *refs, refs_for_each_cb cb, void *cb_data)
{
	struct refs_for_each_ref_options opts = { 0 };
	return refs_for_each_ref_ext(refs, cb, cb_data, &opts);
}

int refs_for_each_replace_ref(struct ref_store *refs, refs_for_each_cb cb, void *cb_data)
{
	const char *git_replace_ref_base = ref_namespace[NAMESPACE_REPLACE].ref;
	struct refs_for_each_ref_options opts = {
		.prefix = git_replace_ref_base,
		.trim_prefix = strlen(git_replace_ref_base),
		.flags = REFS_FOR_EACH_INCLUDE_BROKEN,
	};
	return refs_for_each_ref_ext(refs, cb, cb_data, &opts);
}

static int qsort_strcmp(const void *va, const void *vb)
{
	const char *a = *(const char **)va;
	const char *b = *(const char **)vb;

	return strcmp(a, b);
}

static void find_longest_prefixes_1(struct string_list *out,
				  struct strbuf *prefix,
				  const char **patterns, size_t nr)
{
	size_t i;

	for (i = 0; i < nr; i++) {
		char c = patterns[i][prefix->len];
		if (!c || is_glob_special(c)) {
			string_list_append(out, prefix->buf);
			return;
		}
	}

	i = 0;
	while (i < nr) {
		size_t end;

		/*
		* Set "end" to the index of the element _after_ the last one
		* in our group.
		*/
		for (end = i + 1; end < nr; end++) {
			if (patterns[i][prefix->len] != patterns[end][prefix->len])
				break;
		}

		strbuf_addch(prefix, patterns[i][prefix->len]);
		find_longest_prefixes_1(out, prefix, patterns + i, end - i);
		strbuf_setlen(prefix, prefix->len - 1);

		i = end;
	}
}

static void find_longest_prefixes(struct string_list *out,
				  const char **patterns)
{
	struct strvec sorted = STRVEC_INIT;
	struct strbuf prefix = STRBUF_INIT;

	strvec_pushv(&sorted, patterns);
	QSORT(sorted.v, sorted.nr, qsort_strcmp);

	find_longest_prefixes_1(out, &prefix, sorted.v, sorted.nr);

	strvec_clear(&sorted);
	strbuf_release(&prefix);
}

int refs_for_each_ref_in_prefixes(struct ref_store *ref_store,
				  const char **prefixes,
				  const struct refs_for_each_ref_options *opts,
				  refs_for_each_cb cb, void *cb_data)
{
	struct string_list longest_prefixes = STRING_LIST_INIT_DUP;
	struct string_list_item *prefix;
	int ret = 0;

	if (opts->prefix)
		BUG("refs_for_each_ref_in_prefixes called with specific prefix");

	find_longest_prefixes(&longest_prefixes, prefixes);

	for_each_string_list_item(prefix, &longest_prefixes) {
		struct refs_for_each_ref_options prefix_opts = *opts;
		prefix_opts.prefix = prefix->string;

		ret = refs_for_each_ref_ext(ref_store, cb, cb_data,
					    &prefix_opts);
		if (ret)
			break;
	}

	string_list_clear(&longest_prefixes, 0);
	return ret;
}

static int refs_read_special_head(struct ref_store *ref_store,
				  const char *refname, struct object_id *oid,
				  struct strbuf *referent, unsigned int *type,
				  int *failure_errno)
{
	struct strbuf full_path = STRBUF_INIT;
	struct strbuf content = STRBUF_INIT;
	int result = -1;
	strbuf_addf(&full_path, "%s/%s", ref_store->gitdir, refname);

	if (strbuf_read_file(&content, full_path.buf, 0) < 0) {
		*failure_errno = errno;
		goto done;
	}

	result = parse_loose_ref_contents(ref_store->repo->hash_algo, content.buf,
					  oid, referent, type, NULL, failure_errno);

done:
	strbuf_release(&full_path);
	strbuf_release(&content);
	return result;
}

int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
		      struct object_id *oid, struct strbuf *referent,
		      unsigned int *type, int *failure_errno)
{
	assert(failure_errno);
	if (is_pseudo_ref(refname))
		return refs_read_special_head(ref_store, refname, oid, referent,
					      type, failure_errno);

	return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
					   type, failure_errno);
}

int refs_read_symbolic_ref(struct ref_store *ref_store, const char *refname,
			   struct strbuf *referent)
{
	return ref_store->be->read_symbolic_ref(ref_store, refname, referent);
}

const char *refs_resolve_ref_unsafe(struct ref_store *refs,
				    const char *refname,
				    int resolve_flags,
				    struct object_id *oid,
				    int *flags)
{
	static struct strbuf sb_refname = STRBUF_INIT;
	struct object_id unused_oid;
	int unused_flags;
	int symref_count;

	if (!oid)
		oid = &unused_oid;
	if (!flags)
		flags = &unused_flags;

	*flags = 0;

	if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
		if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
		    !refname_is_safe(refname))
			return NULL;

		/*
		 * repo_dwim_ref() uses REF_ISBROKEN to distinguish between
		 * missing refs and refs that were present but invalid,
		 * to complain about the latter to stderr.
		 *
		 * We don't know whether the ref exists, so don't set
		 * REF_ISBROKEN yet.
		 */
		*flags |= REF_BAD_NAME;
	}

	for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
		unsigned int read_flags = 0;
		int failure_errno;

		if (refs_read_raw_ref(refs, refname, oid, &sb_refname,
				      &read_flags, &failure_errno)) {
			*flags |= read_flags;

			/* In reading mode, refs must eventually resolve */
			if (resolve_flags & RESOLVE_REF_READING)
				return NULL;

			/*
			 * Otherwise a missing ref is OK. But the files backend
			 * may show errors besides ENOENT if there are
			 * similarly-named refs.
			 */
			if (failure_errno != ENOENT &&
			    failure_errno != EISDIR &&
			    failure_errno != ENOTDIR)
				return NULL;

			oidclr(oid, refs->repo->hash_algo);
			if (*flags & REF_BAD_NAME)
				*flags |= REF_ISBROKEN;
			return refname;
		}

		*flags |= read_flags;

		if (!(read_flags & REF_ISSYMREF)) {
			if (*flags & REF_BAD_NAME) {
				oidclr(oid, refs->repo->hash_algo);
				*flags |= REF_ISBROKEN;
			}
			return refname;
		}

		refname = sb_refname.buf;
		if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
			oidclr(oid, refs->repo->hash_algo);
			return refname;
		}
		if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
			if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
			    !refname_is_safe(refname))
				return NULL;

			*flags |= REF_ISBROKEN | REF_BAD_NAME;
		}
	}

	return NULL;
}

void refs_create_refdir_stubs(struct repository *repo, const char *refdir,
			      const char *refs_heads_content)
{
	struct strbuf path = STRBUF_INIT;

	strbuf_addf(&path, "%s/HEAD", refdir);
	write_file(path.buf, "ref: refs/heads/.invalid");
	adjust_shared_perm(repo, path.buf);

	strbuf_reset(&path);
	strbuf_addf(&path, "%s/refs", refdir);
	safe_create_dir(repo, path.buf, 1);

	if (refs_heads_content) {
		strbuf_reset(&path);
		strbuf_addf(&path, "%s/refs/heads", refdir);
		write_file(path.buf, "%s", refs_heads_content);
		adjust_shared_perm(repo, path.buf);
	}

	strbuf_release(&path);
}

/* backend functions */
int ref_store_create_on_disk(struct ref_store *refs, int flags, struct strbuf *err)
{
	int ret = refs->be->create_on_disk(refs, flags, err);

	if (!ret) {
		/* Creation of stubs for linked worktrees are handled in the worktree code. */
		if (!(flags & REF_STORE_CREATE_ON_DISK_IS_WORKTREE) && refs->repo->ref_storage_payload) {
			refs_create_refdir_stubs(refs->repo, refs->repo->gitdir,
						 "repository uses alternate refs storage");
		} else if (ref_storage_format_by_name(refs->be->name) != REF_STORAGE_FORMAT_FILES) {
			struct strbuf msg = STRBUF_INIT;
			strbuf_addf(&msg, "this repository uses the %s format", refs->be->name);
			refs_create_refdir_stubs(refs->repo, refs->gitdir, msg.buf);
			strbuf_release(&msg);
		}
	}

	return ret;
}

int ref_store_remove_on_disk(struct ref_store *refs, struct strbuf *err)
{
	int ret = refs->be->remove_on_disk(refs, err);

	if (!ret) {
		enum ref_storage_format format = ref_storage_format_by_name(refs->be->name);
		struct strbuf sb = STRBUF_INIT;

		/* Backends apart from the files backend create stubs. */
		if (format == REF_STORAGE_FORMAT_FILES)
			return ret;

		/* Alternate refs backend require stubs in the gitdir. */
		if (refs->repo->ref_storage_payload)
			return ret;

		strbuf_addf(&sb, "%s/HEAD", refs->gitdir);
		if (unlink(sb.buf) < 0) {
			strbuf_addf(err, "could not delete stub HEAD: %s",
				    strerror(errno));
			ret = -1;
		}
		strbuf_reset(&sb);

		strbuf_addf(&sb, "%s/refs/heads", refs->gitdir);
		if (unlink(sb.buf) < 0) {
			strbuf_addf(err, "could not delete stub heads: %s",
				    strerror(errno));
			ret = -1;
		}
		strbuf_reset(&sb);

		strbuf_addf(&sb, "%s/refs", refs->gitdir);
		if (rmdir(sb.buf) < 0) {
			strbuf_addf(err, "could not delete refs directory: %s",
				    strerror(errno));
			ret = -1;
		}

		strbuf_release(&sb);
	}

	return ret;
}

int repo_resolve_gitlink_ref(struct repository *r,
			     const char *submodule, const char *refname,
			     struct object_id *oid)
{
	struct ref_store *refs;
	int flags;

	refs = repo_get_submodule_ref_store(r, submodule);
	if (!refs)
		return -1;

	if (!refs_resolve_ref_unsafe(refs, refname, 0, oid, &flags) ||
	    is_null_oid(oid))
		return -1;
	return 0;
}

/*
 * Look up a ref store by name. If that ref_store hasn't been
 * registered yet, return NULL.
 */
static struct ref_store *lookup_ref_store_map(struct strmap *map,
					      const char *name)
{
	struct strmap_entry *entry;

	if (!map->map.tablesize)
		/* It's initialized on demand in register_ref_store(). */
		return NULL;

	entry = strmap_get_entry(map, name);
	return entry ? entry->value : NULL;
}

/*
 * Create, record, and return a ref_store instance for the specified
 * gitdir using the given ref storage format.
 */
static struct ref_store *ref_store_init(struct repository *repo,
					enum ref_storage_format format,
					const char *gitdir,
					unsigned int flags)
{
	const struct ref_storage_be *be;
	struct ref_store *refs;

	be = find_ref_storage_backend(format);
	if (!be)
		BUG("reference backend is unknown");

	/*
	 * TODO Send in a 'struct worktree' instead of a 'gitdir', and
	 * allow the backend to handle how it wants to deal with worktrees.
	 */
	refs = be->init(repo, repo->ref_storage_payload, gitdir, flags);
	return refs;
}

void ref_store_release(struct ref_store *ref_store)
{
	ref_store->be->release(ref_store);
	free(ref_store->gitdir);
}

struct ref_store *get_main_ref_store(struct repository *r)
{
	if (r->refs_private)
		return r->refs_private;

	if (!r->gitdir)
		BUG("attempting to get main_ref_store outside of repository");

	r->refs_private = ref_store_init(r, r->ref_storage_format,
					 r->gitdir, REF_STORE_ALL_CAPS);
	r->refs_private = maybe_debug_wrap_ref_store(r->gitdir, r->refs_private);
	return r->refs_private;
}

/*
 * Associate a ref store with a name. It is a fatal error to call this
 * function twice for the same name.
 */
static void register_ref_store_map(struct strmap *map,
				   const char *type,
				   struct ref_store *refs,
				   const char *name)
{
	if (!map->map.tablesize)
		strmap_init(map);
	if (strmap_put(map, name, refs))
		BUG("%s ref_store '%s' initialized twice", type, name);
}

struct ref_store *repo_get_submodule_ref_store(struct repository *repo,
					       const char *submodule)
{
	struct strbuf submodule_sb = STRBUF_INIT;
	struct ref_store *refs;
	char *to_free = NULL;
	size_t len;
	struct repository *subrepo;

	if (!submodule)
		return NULL;

	len = strlen(submodule);
	while (len && is_dir_sep(submodule[len - 1]))
		len--;
	if (!len)
		return NULL;

	if (submodule[len])
		/* We need to strip off one or more trailing slashes */
		submodule = to_free = xmemdupz(submodule, len);

	refs = lookup_ref_store_map(&repo->submodule_ref_stores, submodule);
	if (refs)
		goto done;

	strbuf_addstr(&submodule_sb, submodule);
	if (!is_nonbare_repository_dir(&submodule_sb))
		goto done;

	if (submodule_to_gitdir(repo, &submodule_sb, submodule))
		goto done;

	subrepo = xmalloc(sizeof(*subrepo));

	if (repo_submodule_init(subrepo, repo, submodule,
				null_oid(the_hash_algo))) {
		free(subrepo);
		goto done;
	}
	refs = ref_store_init(subrepo, subrepo->ref_storage_format,
			      submodule_sb.buf,
			      REF_STORE_READ | REF_STORE_ODB);
	register_ref_store_map(&repo->submodule_ref_stores, "submodule",
			       refs, submodule);

done:
	strbuf_release(&submodule_sb);
	free(to_free);

	return refs;
}

struct ref_store *get_worktree_ref_store(const struct worktree *wt)
{
	struct ref_store *refs;
	const char *id;

	if (wt->is_current)
		return get_main_ref_store(wt->repo);

	id = wt->id ? wt->id : "/";
	refs = lookup_ref_store_map(&wt->repo->worktree_ref_stores, id);
	if (refs)
		return refs;

	if (wt->id) {
		struct strbuf common_path = STRBUF_INIT;
		repo_common_path_append(wt->repo, &common_path,
					"worktrees/%s", wt->id);
		refs = ref_store_init(wt->repo, wt->repo->ref_storage_format,
				      common_path.buf, REF_STORE_ALL_CAPS);
		strbuf_release(&common_path);
	} else {
		refs = ref_store_init(wt->repo, wt->repo->ref_storage_format,
				      wt->repo->commondir, REF_STORE_ALL_CAPS);
	}

	if (refs)
		register_ref_store_map(&wt->repo->worktree_ref_stores,
				       "worktree", refs, id);

	return refs;
}

void base_ref_store_init(struct ref_store *refs, struct repository *repo,
			 const char *path, const struct ref_storage_be *be)
{
	refs->be = be;
	refs->repo = repo;
	refs->gitdir = xstrdup(path);
}

int refs_optimize(struct ref_store *refs, struct refs_optimize_opts *opts)
{
	return refs->be->optimize(refs, opts);
}

int refs_optimize_required(struct ref_store *refs,
			   struct refs_optimize_opts *opts,
			   bool *required)
{
	return refs->be->optimize_required(refs, opts, required);
}

int reference_get_peeled_oid(struct repository *repo,
			     const struct reference *ref,
			     struct object_id *peeled_oid)
{
	if (ref->peeled_oid) {
		oidcpy(peeled_oid, ref->peeled_oid);
		return 0;
	}

	return peel_object(repo, ref->oid, peeled_oid, 0) ? -1 : 0;
}

int refs_update_symref(struct ref_store *refs, const char *ref,
		       const char *target, const char *logmsg)
{
	return refs_update_symref_extended(refs, ref, target, logmsg, NULL, 0);
}

int refs_update_symref_extended(struct ref_store *refs, const char *ref,
		       const char *target, const char *logmsg,
		       struct strbuf *referent, int create_only)
{
	struct ref_transaction *transaction;
	struct strbuf err = STRBUF_INIT;
	int ret = 0, prepret = 0;

	transaction = ref_store_transaction_begin(refs, 0, &err);
	if (!transaction) {
	error_return:
		ret = error("%s", err.buf);
		goto cleanup;
	}
	if (create_only) {
		if (ref_transaction_create(transaction, ref, NULL, target,
					   REF_NO_DEREF, logmsg, &err))
			goto error_return;
		prepret = ref_transaction_prepare(transaction, &err);
		if (prepret && prepret != REF_TRANSACTION_ERROR_CREATE_EXISTS)
			goto error_return;
	} else {
		if (ref_transaction_update(transaction, ref, NULL, NULL,
					   target, NULL, REF_NO_DEREF,
					   logmsg, &err) ||
			ref_transaction_prepare(transaction, &err))
			goto error_return;
	}

	if (referent && refs_read_symbolic_ref(refs, ref, referent) == NOT_A_SYMREF) {
		struct object_id oid;
		if (!refs_read_ref(refs, ref, &oid)) {
			strbuf_addstr(referent, oid_to_hex(&oid));
			ret = NOT_A_SYMREF;
		}
	}

	if (prepret == REF_TRANSACTION_ERROR_CREATE_EXISTS)
		goto cleanup;

	if (ref_transaction_commit(transaction, &err))
		goto error_return;

cleanup:
	strbuf_release(&err);
	if (transaction)
		ref_transaction_free(transaction);

	return ret;
}

/*
 * Write an error to `err` and return a nonzero value iff the same
 * refname appears multiple times in `refnames`. `refnames` must be
 * sorted on entry to this function.
 */
static int ref_update_reject_duplicates(struct string_list *refnames,
					struct strbuf *err)
{
	size_t i, n = refnames->nr;

	assert(err);

	for (i = 1; i < n; i++) {
		int cmp = strcmp(refnames->items[i - 1].string,
				 refnames->items[i].string);

		if (!cmp) {
			strbuf_addf(err,
				    _("multiple updates for ref '%s' not allowed"),
				    refnames->items[i].string);
			return 1;
		} else if (cmp > 0) {
			BUG("ref_update_reject_duplicates() received unsorted list");
		}
	}
	return 0;
}

struct transaction_feed_cb_data {
	size_t index;
	struct strbuf buf;
};

static int transaction_hook_feed_stdin(int hook_stdin_fd, void *pp_cb, void *pp_task_cb)
{
	struct hook_cb_data *hook_cb = pp_cb;
	struct ref_transaction *transaction = hook_cb->options->feed_pipe_ctx;
	struct transaction_feed_cb_data *feed_cb_data = pp_task_cb;
	struct strbuf *buf = &feed_cb_data->buf;
	struct ref_update *update;
	size_t i = feed_cb_data->index++;
	int ret;

	if (i >= transaction->nr)
		return 1; /* No more refs to process */

	update = transaction->updates[i];

	if (update->flags & REF_LOG_ONLY)
		return 0;

	strbuf_reset(buf);

	if (!(update->flags & REF_HAVE_OLD))
		strbuf_addf(buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
	else if (update->old_target)
		strbuf_addf(buf, "ref:%s ", update->old_target);
	else
		strbuf_addf(buf, "%s ", oid_to_hex(&update->old_oid));

	if (!(update->flags & REF_HAVE_NEW))
		strbuf_addf(buf, "%s ", oid_to_hex(null_oid(the_hash_algo)));
	else if (update->new_target)
		strbuf_addf(buf, "ref:%s ", update->new_target);
	else
		strbuf_addf(buf, "%s ", oid_to_hex(&update->new_oid));

	strbuf_addf(buf, "%s\n", update->refname);

	ret = write_in_full(hook_stdin_fd, buf->buf, buf->len);
	if (ret < 0 && errno != EPIPE)
		return ret;

	return 0; /* no more input to feed */
}

static void *transaction_feed_cb_data_alloc(void *feed_pipe_ctx UNUSED)
{
	struct transaction_feed_cb_data *data;
	CALLOC_ARRAY(data, 1);
	strbuf_init(&data->buf, 0);
	data->index = 0;
	return data;
}

static void transaction_feed_cb_data_free(void *data)
{
	struct transaction_feed_cb_data *d = data;
	if (!d)
		return;
	strbuf_release(&d->buf);
	free(d);
}

static int run_transaction_hook(struct ref_transaction *transaction,
				const char *state)
{
	struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
	int ret = 0;

	strvec_push(&opt.args, state);

	opt.feed_pipe = transaction_hook_feed_stdin;
	opt.feed_pipe_ctx = transaction;
	opt.feed_pipe_cb_data_alloc = transaction_feed_cb_data_alloc;
	opt.feed_pipe_cb_data_free = transaction_feed_cb_data_free;

	ret = run_hooks_opt(transaction->ref_store->repo, "reference-transaction", &opt);

	return ret;
}

int ref_transaction_prepare(struct ref_transaction *transaction,
			    struct strbuf *err)
{
	struct ref_store *refs = transaction->ref_store;
	int ret;

	switch (transaction->state) {
	case REF_TRANSACTION_OPEN:
		/* Good. */
		break;
	case REF_TRANSACTION_PREPARED:
		BUG("prepare called twice on reference transaction");
		break;
	case REF_TRANSACTION_CLOSED:
		BUG("prepare called on a closed reference transaction");
		break;
	default:
		BUG("unexpected reference transaction state");
		break;
	}

	if (refs->repo->disable_ref_updates) {
		strbuf_addstr(err,
			      _("ref updates forbidden inside quarantine environment"));
		return -1;
	}

	string_list_sort(&transaction->refnames);
	if (ref_update_reject_duplicates(&transaction->refnames, err))
		return REF_TRANSACTION_ERROR_GENERIC;

	/* Preparing checks before locking references */
	ret = run_transaction_hook(transaction, "preparing");
	if (ret) {
		ref_transaction_abort(transaction, err);
		die(_(abort_by_ref_transaction_hook), "preparing");
	}

	ret = refs->be->transaction_prepare(refs, transaction, err);
	if (ret)
		return ret;

	ret = run_transaction_hook(transaction, "prepared");
	if (ret) {
		ref_transaction_abort(transaction, err);
		die(_(abort_by_ref_transaction_hook), "prepared");
	}

	return 0;
}

int ref_transaction_abort(struct ref_transaction *transaction,
			  struct strbuf *err)
{
	struct ref_store *refs = transaction->ref_store;
	int ret = 0;

	switch (transaction->state) {
	case REF_TRANSACTION_OPEN:
		/* No need to abort explicitly. */
		break;
	case REF_TRANSACTION_PREPARED:
		ret = refs->be->transaction_abort(refs, transaction, err);
		break;
	case REF_TRANSACTION_CLOSED:
		BUG("abort called on a closed reference transaction");
		break;
	default:
		BUG("unexpected reference transaction state");
		break;
	}

	run_transaction_hook(transaction, "aborted");

	ref_transaction_free(transaction);
	return ret;
}

int ref_transaction_commit(struct ref_transaction *transaction,
			   struct strbuf *err)
{
	struct ref_store *refs = transaction->ref_store;
	int ret;

	switch (transaction->state) {
	case REF_TRANSACTION_OPEN:
		/* Need to prepare first. */
		ret = ref_transaction_prepare(transaction, err);
		if (ret)
			return ret;
		break;
	case REF_TRANSACTION_PREPARED:
		/* Fall through to finish. */
		break;
	case REF_TRANSACTION_CLOSED:
		BUG("commit called on a closed reference transaction");
		break;
	default:
		BUG("unexpected reference transaction state");
		break;
	}

	ret = refs->be->transaction_finish(refs, transaction, err);
	if (!ret && !(transaction->flags & REF_TRANSACTION_FLAG_INITIAL))
		run_transaction_hook(transaction, "committed");
	return ret;
}

enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs,
					  const struct string_list *refnames,
					  const struct string_list *extras,
					  const struct string_list *skip,
					  struct ref_transaction *transaction,
					  unsigned int initial_transaction,
					  struct strbuf *err)
{
	struct strbuf dirname = STRBUF_INIT;
	struct strbuf referent = STRBUF_INIT;
	struct string_list_item *item;
	struct ref_iterator *iter = NULL;
	struct strset conflicting_dirnames;
	struct strset dirnames;
	int ret = REF_TRANSACTION_ERROR_NAME_CONFLICT;

	/*
	 * For the sake of comments in this function, suppose that
	 * refname is "refs/foo/bar".
	 */

	assert(err);

	strset_init(&conflicting_dirnames);
	strset_init(&dirnames);

	for_each_string_list_item(item, refnames) {
		const size_t *update_idx = (size_t *)item->util;
		const char *refname = item->string;
		const char *extra_refname;
		struct object_id oid;
		unsigned int type;
		const char *slash;

		strbuf_reset(&dirname);

		for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
			/*
			 * Just saying "Is a directory" when we e.g. can't
			 * lock some multi-level ref isn't very informative,
			 * the user won't be told *what* is a directory, so
			 * let's not use strerror() below.
			 */
			int ignore_errno;

			/* Expand dirname to the new prefix, not including the trailing slash: */
			strbuf_add(&dirname, refname + dirname.len, slash - refname - dirname.len);

			/*
			 * We are still at a leading dir of the refname (e.g.,
			 * "refs/foo"; if there is a reference with that name,
			 * it is a conflict, *unless* it is in skip.
			 */
			if (skip && string_list_has_string(skip, dirname.buf))
				continue;

			/*
			 * If we've already seen the directory we don't need to
			 * process it again. Skip it to avoid checking common
			 * prefixes like "refs/heads/" repeatedly.
			 */
			if (!strset_add(&dirnames, dirname.buf))
				continue;

			if (!initial_transaction &&
			    (strset_contains(&conflicting_dirnames, dirname.buf) ||
			     !refs_read_raw_ref(refs, dirname.buf, &oid, &referent,
						&type, &ignore_errno))) {

				strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
					    dirname.buf, refname);

				if (transaction && ref_transaction_maybe_set_rejected(
					    transaction, *update_idx,
					    REF_TRANSACTION_ERROR_NAME_CONFLICT, err)) {
					strset_remove(&dirnames, dirname.buf);
					strset_add(&conflicting_dirnames, dirname.buf);
					goto next_ref;
				}

				goto cleanup;
			}

			if (extras && string_list_has_string(extras, dirname.buf)) {
				strbuf_addf(err, _("cannot process '%s' and '%s' at the same time"),
					    refname, dirname.buf);

				if (transaction && ref_transaction_maybe_set_rejected(
					    transaction, *update_idx,
					    REF_TRANSACTION_ERROR_NAME_CONFLICT, err)) {
					strset_remove(&dirnames, dirname.buf);
					goto next_ref;
				}

				goto cleanup;
			}
		}

		/*
		 * We are at the leaf of our refname (e.g., "refs/foo/bar").
		 * There is no point in searching for a reference with that
		 * name, because a refname isn't considered to conflict with
		 * itself. But we still need to check for references whose
		 * names are in the "refs/foo/bar/" namespace, because they
		 * *do* conflict.
		 */
		strbuf_addstr(&dirname, refname + dirname.len);
		strbuf_addch(&dirname, '/');

		if (!initial_transaction) {
			int ok;

			if (!iter)
				iter = refs_ref_iterator_begin(refs, dirname.buf, NULL, 0,
							       REFS_FOR_EACH_INCLUDE_BROKEN);
			else if (ref_iterator_seek(iter, dirname.buf,
						   REF_ITERATOR_SEEK_SET_PREFIX) < 0)
				goto cleanup;

			while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
				if (skip &&
				    string_list_has_string(skip, iter->ref.name))
					continue;
				strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
					    iter->ref.name, refname);

				if (transaction && ref_transaction_maybe_set_rejected(
					    transaction, *update_idx,
					    REF_TRANSACTION_ERROR_NAME_CONFLICT, err))
					goto next_ref;

				goto cleanup;
			}

			if (ok != ITER_DONE)
				BUG("error while iterating over references");
		}

		extra_refname = find_descendant_ref(dirname.buf, extras, skip);
		if (extra_refname) {
			strbuf_addf(err, _("cannot process '%s' and '%s' at the same time"),
				    refname, extra_refname);

			if (transaction && ref_transaction_maybe_set_rejected(
				    transaction, *update_idx,
				    REF_TRANSACTION_ERROR_NAME_CONFLICT, err))
				goto next_ref;

			goto cleanup;
		}
next_ref:;
	}

	ret = 0;

cleanup:
	strbuf_release(&referent);
	strbuf_release(&dirname);
	strset_clear(&conflicting_dirnames);
	strset_clear(&dirnames);
	ref_iterator_free(iter);
	return ret;
}

enum ref_transaction_error refs_verify_refname_available(
	struct ref_store *refs,
	const char *refname,
	const struct string_list *extras,
	const struct string_list *skip,
	unsigned int initial_transaction,
	struct strbuf *err)
{
	struct string_list_item item = { .string = (char *) refname };
	struct string_list refnames = {
		.items = &item,
		.nr = 1,
	};

	return refs_verify_refnames_available(refs, &refnames, extras, skip,
					      NULL, initial_transaction, err);
}

struct do_for_each_reflog_help {
	each_reflog_fn *fn;
	void *cb_data;
};

static int do_for_each_reflog_helper(const struct reference *ref, void *cb_data)
{
	struct do_for_each_reflog_help *hp = cb_data;
	return hp->fn(ref->name, hp->cb_data);
}

int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_data)
{
	struct ref_iterator *iter;
	struct do_for_each_reflog_help hp = { fn, cb_data };

	iter = refs->be->reflog_iterator_begin(refs);

	return do_for_each_ref_iterator(iter, do_for_each_reflog_helper, &hp);
}

int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
				     const char *refname,
				     each_reflog_ent_fn fn,
				     void *cb_data)
{
	return refs->be->for_each_reflog_ent_reverse(refs, refname,
						     fn, cb_data);
}

int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
			     each_reflog_ent_fn fn, void *cb_data)
{
	return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data);
}

int refs_reflog_exists(struct ref_store *refs, const char *refname)
{
	return refs->be->reflog_exists(refs, refname);
}

int refs_create_reflog(struct ref_store *refs, const char *refname,
		       struct strbuf *err)
{
	return refs->be->create_reflog(refs, refname, err);
}

int refs_delete_reflog(struct ref_store *refs, const char *refname)
{
	return refs->be->delete_reflog(refs, refname);
}

int refs_reflog_expire(struct ref_store *refs,
		       const char *refname,
		       unsigned int flags,
		       reflog_expiry_prepare_fn prepare_fn,
		       reflog_expiry_should_prune_fn should_prune_fn,
		       reflog_expiry_cleanup_fn cleanup_fn,
		       void *policy_cb_data)
{
	return refs->be->reflog_expire(refs, refname, flags,
				       prepare_fn, should_prune_fn,
				       cleanup_fn, policy_cb_data);
}

void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
					    ref_transaction_for_each_queued_update_fn cb,
					    void *cb_data)
{
	for (size_t i = 0; i < transaction->nr; i++) {
		struct ref_update *update = transaction->updates[i];

		cb(update->refname,
		   (update->flags & REF_HAVE_OLD) ? &update->old_oid : NULL,
		   (update->flags & REF_HAVE_NEW) ? &update->new_oid : NULL,
		   cb_data);
	}
}

void ref_transaction_for_each_rejected_update(struct ref_transaction *transaction,
					      ref_transaction_for_each_rejected_update_fn cb,
					      void *cb_data)
{
	if (!transaction->rejections)
		return;

	for (size_t i = 0; i < transaction->rejections->nr; i++) {
		size_t update_index = transaction->rejections->update_indices[i];
		struct ref_update *update = transaction->updates[update_index];

		if (!update->rejection_err)
			continue;

		cb(update->refname,
		   (update->flags & REF_HAVE_OLD) ? &update->old_oid : NULL,
		   (update->flags & REF_HAVE_NEW) ? &update->new_oid : NULL,
		   update->old_target, update->new_target,
		   update->rejection_err, update->rejection_details, cb_data);
	}
}

int refs_delete_refs(struct ref_store *refs, const char *logmsg,
		     struct string_list *refnames, unsigned int flags)
{
	struct ref_transaction *transaction;
	struct strbuf err = STRBUF_INIT;
	struct string_list_item *item;
	int ret = 0, failures = 0;
	char *msg;

	if (!refnames->nr)
		return 0;

	msg = normalize_reflog_message(logmsg);

	/*
	 * Since we don't check the references' old_oids, the
	 * individual updates can't fail, so we can pack all of the
	 * updates into a single transaction.
	 */
	transaction = ref_store_transaction_begin(refs, 0, &err);
	if (!transaction) {
		ret = error("%s", err.buf);
		goto out;
	}

	for_each_string_list_item(item, refnames) {
		ret = ref_transaction_delete(transaction, item->string,
					     NULL, NULL, flags, msg, &err);
		if (ret) {
			warning(_("could not delete reference %s: %s"),
				item->string, err.buf);
			strbuf_reset(&err);
			failures = 1;
		}
	}

	ret = ref_transaction_commit(transaction, &err);
	if (ret) {
		if (refnames->nr == 1)
			error(_("could not delete reference %s: %s"),
			      refnames->items[0].string, err.buf);
		else
			error(_("could not delete references: %s"), err.buf);
	}

out:
	if (!ret && failures)
		ret = -1;
	ref_transaction_free(transaction);
	strbuf_release(&err);
	free(msg);
	return ret;
}

int refs_rename_ref(struct ref_store *refs, const char *oldref,
		    const char *newref, const char *logmsg)
{
	char *msg;
	int retval;

	msg = normalize_reflog_message(logmsg);
	retval = refs->be->rename_ref(refs, oldref, newref, msg);
	free(msg);
	return retval;
}

int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
		    const char *newref, const char *logmsg)
{
	char *msg;
	int retval;

	msg = normalize_reflog_message(logmsg);
	retval = refs->be->copy_ref(refs, oldref, newref, msg);
	free(msg);
	return retval;
}

const char *ref_update_original_update_refname(struct ref_update *update)
{
	while (update->parent_update)
		update = update->parent_update;

	return update->refname;
}

int ref_update_has_null_new_value(struct ref_update *update)
{
	return !update->new_target && is_null_oid(&update->new_oid);
}

enum ref_transaction_error ref_update_check_old_target(const char *referent,
						       struct ref_update *update,
						       struct strbuf *err)
{
	if (!update->old_target)
		BUG("called without old_target set");

	if (!strcmp(referent, update->old_target))
		return 0;

	if (!strcmp(referent, "")) {
		strbuf_addf(err, "verifying symref target: '%s': "
			    "reference is missing but expected %s",
			    ref_update_original_update_refname(update),
			    update->old_target);
		return REF_TRANSACTION_ERROR_NONEXISTENT_REF;
	}

	strbuf_addf(err, "verifying symref target: '%s': is at %s but expected %s",
			    ref_update_original_update_refname(update),
			    referent, update->old_target);
	return REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE;
}

struct migration_data {
	struct ref_store *old_refs;
	struct ref_transaction *transaction;
	struct strbuf *errbuf;
	struct strbuf sb, name, mail;
	uint64_t index;
};

static int migrate_one_ref(const struct reference *ref, void *cb_data)
{
	struct migration_data *data = cb_data;
	struct strbuf symref_target = STRBUF_INIT;
	int ret;

	if (ref->flags & REF_ISSYMREF) {
		ret = refs_read_symbolic_ref(data->old_refs, ref->name, &symref_target);
		if (ret < 0)
			goto done;

		ret = ref_transaction_update(data->transaction, ref->name, NULL, null_oid(the_hash_algo),
					     symref_target.buf, NULL,
					     REF_SKIP_CREATE_REFLOG | REF_NO_DEREF, NULL, data->errbuf);
		if (ret < 0)
			goto done;
	} else {
		ret = ref_transaction_create(data->transaction, ref->name, ref->oid, NULL,
					     REF_SKIP_CREATE_REFLOG | REF_SKIP_OID_VERIFICATION,
					     NULL, data->errbuf);
		if (ret < 0)
			goto done;
	}

done:
	strbuf_release(&symref_target);
	return ret;
}

static int migrate_one_reflog_entry(const char *refname,
				    struct object_id *old_oid,
				    struct object_id *new_oid,
				    const char *committer,
				    timestamp_t timestamp, int tz,
				    const char *msg, void *cb_data)
{
	struct migration_data *data = cb_data;
	struct ident_split ident;
	const char *date;
	int ret;

	if (split_ident_line(&ident, committer, strlen(committer)) < 0)
		return -1;

	strbuf_reset(&data->name);
	strbuf_add(&data->name, ident.name_begin, ident.name_end - ident.name_begin);
	strbuf_reset(&data->mail);
	strbuf_add(&data->mail, ident.mail_begin, ident.mail_end - ident.mail_begin);

	date = show_date(timestamp, tz, DATE_MODE(NORMAL));
	strbuf_reset(&data->sb);
	strbuf_addstr(&data->sb, fmt_ident(data->name.buf, data->mail.buf, WANT_BLANK_IDENT, date, 0));

	ret = ref_transaction_update_reflog(data->transaction, refname,
					    new_oid, old_oid, data->sb.buf,
					    msg, data->index++, data->errbuf);
	return ret;
}

static int migrate_one_reflog(const char *refname, void *cb_data)
{
	struct migration_data *migration_data = cb_data;
	return refs_for_each_reflog_ent(migration_data->old_refs, refname,
					migrate_one_reflog_entry, migration_data);
}

static int move_files(const char *from_path, const char *to_path, struct strbuf *errbuf)
{
	struct strbuf from_buf = STRBUF_INIT, to_buf = STRBUF_INIT;
	size_t from_len, to_len;
	DIR *from_dir;
	int ret;

	from_dir = opendir(from_path);
	if (!from_dir) {
		strbuf_addf(errbuf, "could not open source directory '%s': %s",
			    from_path, strerror(errno));
		ret = -1;
		goto done;
	}

	strbuf_addstr(&from_buf, from_path);
	strbuf_complete(&from_buf, '/');
	from_len = from_buf.len;

	strbuf_addstr(&to_buf, to_path);
	strbuf_complete(&to_buf, '/');
	to_len = to_buf.len;

	while (1) {
		struct dirent *ent;

		errno = 0;
		ent = readdir(from_dir);
		if (!ent)
			break;

		if (!strcmp(ent->d_name, ".") ||
		    !strcmp(ent->d_name, ".."))
			continue;

		strbuf_setlen(&from_buf, from_len);
		strbuf_addstr(&from_buf, ent->d_name);

		strbuf_setlen(&to_buf, to_len);
		strbuf_addstr(&to_buf, ent->d_name);

		ret = rename(from_buf.buf, to_buf.buf);
		if (ret < 0) {
			strbuf_addf(errbuf, "could not link file '%s' to '%s': %s",
				    from_buf.buf, to_buf.buf, strerror(errno));
			goto done;
		}
	}

	if (errno) {
		strbuf_addf(errbuf, "could not read entry from directory '%s': %s",
			    from_path, strerror(errno));
		ret = -1;
		goto done;
	}

	ret = 0;

done:
	strbuf_release(&from_buf);
	strbuf_release(&to_buf);
	if (from_dir)
		closedir(from_dir);
	return ret;
}

static int has_worktrees(void)
{
	struct worktree **worktrees = get_worktrees();
	int ret = 0;
	size_t i;

	for (i = 0; worktrees[i]; i++) {
		if (is_main_worktree(worktrees[i]))
			continue;
		ret = 1;
	}

	free_worktrees(worktrees);
	return ret;
}

int repo_migrate_ref_storage_format(struct repository *repo,
				    enum ref_storage_format format,
				    unsigned int flags,
				    struct strbuf *errbuf)
{
	struct ref_store *old_refs = NULL, *new_refs = NULL;
	struct refs_for_each_ref_options for_each_ref_opts = {
		.flags = REFS_FOR_EACH_INCLUDE_ROOT_REFS | REFS_FOR_EACH_INCLUDE_BROKEN,
	};
	struct ref_transaction *transaction = NULL;
	struct strbuf new_gitdir = STRBUF_INIT;
	struct migration_data data = {
		.sb = STRBUF_INIT,
		.name = STRBUF_INIT,
		.mail = STRBUF_INIT,
	};
	int did_migrate_refs = 0;
	int ret;

	if (repo->ref_storage_format == format) {
		strbuf_addstr(errbuf, "current and new ref storage format are equal");
		ret = -1;
		goto done;
	}

	old_refs = get_main_ref_store(repo);

	/*
	 * Worktrees complicate the migration because every worktree has a
	 * separate ref storage. While it should be feasible to implement, this
	 * is pushed out to a future iteration.
	 *
	 * TODO: we should really be passing the caller-provided repository to
	 * `has_worktrees()`, but our worktree subsystem doesn't yet support
	 * that.
	 */
	if (has_worktrees()) {
		strbuf_addstr(errbuf, "migrating repositories with worktrees is not supported yet");
		ret = -1;
		goto done;
	}

	/*
	 * The overall logic looks like this:
	 *
	 *   1. Set up a new temporary directory and initialize it with the new
	 *      format. This is where all refs will be migrated into.
	 *
	 *   2. Enumerate all refs and write them into the new ref storage.
	 *      This operation is safe as we do not yet modify the main
	 *      repository.
	 *
	 *   3. Enumerate all reflogs and write them into the new ref storage.
	 *      This operation is safe as we do not yet modify the main
	 *      repository.
	 *
	 *   4. If we're in dry-run mode then we are done and can hand over the
	 *      directory to the caller for inspection. If not, we now start
	 *      with the destructive part.
	 *
	 *   5. Delete the old ref storage from disk. As we have a copy of refs
	 *      in the new ref storage it's okay(ish) if we now get interrupted
	 *      as there is an equivalent copy of all refs available.
	 *
	 *   6. Move the new ref storage files into place.
	 *
	 *  7. Change the repository format to the new ref format.
	 */
	strbuf_addf(&new_gitdir, "%s/%s", old_refs->gitdir, "ref_migration.XXXXXX");
	if (!mkdtemp(new_gitdir.buf)) {
		strbuf_addf(errbuf, "cannot create migration directory: %s",
			    strerror(errno));
		ret = -1;
		goto done;
	}

	new_refs = ref_store_init(repo, format, new_gitdir.buf,
				  REF_STORE_ALL_CAPS);
	ret = ref_store_create_on_disk(new_refs, 0, errbuf);
	if (ret < 0)
		goto done;

	transaction = ref_store_transaction_begin(new_refs, REF_TRANSACTION_FLAG_INITIAL,
						  errbuf);
	if (!transaction)
		goto done;

	data.old_refs = old_refs;
	data.transaction = transaction;
	data.errbuf = errbuf;

	/*
	 * We need to use `refs_for_each_ref_ext()` here so that we can
	 * also include broken refs and symrefs. These would otherwise be
	 * skipped silently.
	 *
	 * Ideally, we would do this call while locking the old ref storage
	 * such that there cannot be any concurrent modifications. We do not
	 * have the infra for that though, and the "files" backend does not
	 * allow for a central lock due to its design. It's thus on the user to
	 * ensure that there are no concurrent writes.
	 */
	ret = refs_for_each_ref_ext(old_refs, migrate_one_ref, &data, &for_each_ref_opts);
	if (ret < 0)
		goto done;

	if (!(flags & REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG)) {
		ret = refs_for_each_reflog(old_refs, migrate_one_reflog, &data);
		if (ret < 0)
			goto done;
	}

	ret = ref_transaction_commit(transaction, errbuf);
	if (ret < 0)
		goto done;
	did_migrate_refs = 1;

	if (flags & REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN) {
		printf(_("Finished dry-run migration of refs, "
			 "the result can be found at '%s'\n"), new_gitdir.buf);
		ret = 0;
		goto done;
	}

	/*
	 * Release the new ref store such that any potentially-open files will
	 * be closed. This is required for platforms like Cygwin, where
	 * renaming an open file results in EPERM.
	 */
	ref_store_release(new_refs);
	FREE_AND_NULL(new_refs);

	/*
	 * Until now we were in the non-destructive phase, where we only
	 * populated the new ref store. From hereon though we are about
	 * to get hands by deleting the old ref store and then moving
	 * the new one into place.
	 *
	 * Assuming that there were no concurrent writes, the new ref
	 * store should have all information. So if we fail from hereon
	 * we may be in an in-between state, but it would still be able
	 * to recover by manually moving remaining files from the
	 * temporary migration directory into place.
	 */
	ret = ref_store_remove_on_disk(old_refs, errbuf);
	if (ret < 0)
		goto done;

	ret = move_files(new_gitdir.buf, old_refs->gitdir, errbuf);
	if (ret < 0)
		goto done;

	if (rmdir(new_gitdir.buf) < 0)
		warning_errno(_("could not remove temporary migration directory '%s'"),
			      new_gitdir.buf);

	/*
	 * We have migrated the repository, so we now need to adjust the
	 * repository format so that clients will use the new ref store.
	 * We also need to swap out the repository's main ref store.
	 */
	initialize_repository_version(hash_algo_by_ptr(repo->hash_algo), format, 1);

	/*
	 * Unset the old ref store and release it. `get_main_ref_store()` will
	 * make sure to lazily re-initialize the repository's ref store with
	 * the new format.
	 */
	ref_store_release(old_refs);
	FREE_AND_NULL(old_refs);
	repo->refs_private = NULL;

	ret = 0;

done:
	if (ret && did_migrate_refs) {
		strbuf_complete(errbuf, '\n');
		strbuf_addf(errbuf, _("migrated refs can be found at '%s'"),
			    new_gitdir.buf);
	}

	if (new_refs) {
		ref_store_release(new_refs);
		free(new_refs);
	}
	ref_transaction_free(transaction);
	strbuf_release(&new_gitdir);
	strbuf_release(&data.sb);
	strbuf_release(&data.name);
	strbuf_release(&data.mail);
	return ret;
}

int ref_update_expects_existing_old_ref(struct ref_update *update)
{
	if (update->flags & REF_LOG_ONLY)
		return 0;

	return (update->flags & REF_HAVE_OLD) &&
		(!is_null_oid(&update->old_oid) || update->old_target);
}

const char *ref_transaction_error_msg(enum ref_transaction_error err)
{
	switch (err) {
	case REF_TRANSACTION_ERROR_NAME_CONFLICT:
		return "refname conflict";
	case REF_TRANSACTION_ERROR_CREATE_EXISTS:
		return "reference already exists";
	case REF_TRANSACTION_ERROR_NONEXISTENT_REF:
		return "reference does not exist";
	case REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE:
		return "incorrect old value provided";
	case REF_TRANSACTION_ERROR_INVALID_NEW_VALUE:
		return "invalid new value provided";
	case REF_TRANSACTION_ERROR_EXPECTED_SYMREF:
		return "expected symref but found regular ref";
	case REF_TRANSACTION_ERROR_CASE_CONFLICT:
		return "reference conflict due to case-insensitive filesystem";
	default:
		return "unknown failure";
	}
}

void refs_compute_filesystem_location(const char *gitdir, const char *payload,
				      bool *is_worktree, struct strbuf *refdir,
				      struct strbuf *ref_common_dir)
{
	struct strbuf sb = STRBUF_INIT;

	*is_worktree = get_common_dir_noenv(ref_common_dir, gitdir);

	if (!payload) {
		/*
		 * We can use the 'gitdir' as the 'refdir' without appending the
		 * worktree path, as the 'gitdir' here is already the worktree
		 * path and is different from 'commondir' denoted by 'ref_common_dir'.
		 */
		strbuf_addstr(refdir, gitdir);
		return;
	}

	if (!is_absolute_path(payload)) {
		strbuf_addf(&sb, "%s/%s", ref_common_dir->buf, payload);
		strbuf_realpath(ref_common_dir, sb.buf, 1);
	} else {
		strbuf_realpath(ref_common_dir, payload, 1);
	}

	strbuf_addbuf(refdir, ref_common_dir);

	if (*is_worktree) {
		const char *wt_id = strrchr(gitdir, '/');
		if (!wt_id)
			BUG("worktree path does not contain slash");
		strbuf_addf(refdir, "/worktrees/%s", wt_id + 1);
	}

	strbuf_release(&sb);
}
