#define USE_THE_REPOSITORY_VARIABLE
#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "object-name.h"
#include "advice.h"
#include "config.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
#include "tag.h"
#include "commit.h"
#include "tree.h"
#include "tree-walk.h"
#include "refs.h"
#include "remote.h"
#include "dir.h"
#include "oid-array.h"
#include "oidtree.h"
#include "packfile.h"
#include "pretty.h"
#include "object-file.h"
#include "read-cache-ll.h"
#include "repo-settings.h"
#include "repository.h"
#include "setup.h"
#include "midx.h"
#include "commit-reach.h"
#include "date.h"
#include "object-file-convert.h"
#include "prio-queue.h"

static int get_oid_oneline(struct repository *r, const char *, struct object_id *,
			   const struct commit_list *);

typedef int (*disambiguate_hint_fn)(struct repository *, const struct object_id *, void *);

struct disambiguate_state {
	int len; /* length of prefix in hex chars */
	char hex_pfx[GIT_MAX_HEXSZ + 1];
	struct object_id bin_pfx;

	struct repository *repo;
	disambiguate_hint_fn fn;
	void *cb_data;
	struct object_id candidate;
	unsigned candidate_exists:1;
	unsigned candidate_checked:1;
	unsigned candidate_ok:1;
	unsigned disambiguate_fn_used:1;
	unsigned ambiguous:1;
	unsigned always_call_fn:1;
};

static void update_candidates(struct disambiguate_state *ds, const struct object_id *current)
{
	/* The hash algorithm of current has already been filtered */
	if (ds->always_call_fn) {
		ds->ambiguous = ds->fn(ds->repo, current, ds->cb_data) ? 1 : 0;
		return;
	}
	if (!ds->candidate_exists) {
		/* this is the first candidate */
		oidcpy(&ds->candidate, current);
		ds->candidate_exists = 1;
		return;
	} else if (oideq(&ds->candidate, current)) {
		/* the same as what we already have seen */
		return;
	}

	if (!ds->fn) {
		/* cannot disambiguate between ds->candidate and current */
		ds->ambiguous = 1;
		return;
	}

	if (!ds->candidate_checked) {
		ds->candidate_ok = ds->fn(ds->repo, &ds->candidate, ds->cb_data);
		ds->disambiguate_fn_used = 1;
		ds->candidate_checked = 1;
	}

	if (!ds->candidate_ok) {
		/* discard the candidate; we know it does not satisfy fn */
		oidcpy(&ds->candidate, current);
		ds->candidate_checked = 0;
		return;
	}

	/* if we reach this point, we know ds->candidate satisfies fn */
	if (ds->fn(ds->repo, current, ds->cb_data)) {
		/*
		 * if both current and candidate satisfy fn, we cannot
		 * disambiguate.
		 */
		ds->candidate_ok = 0;
		ds->ambiguous = 1;
	}

	/* otherwise, current can be discarded and candidate is still good */
}

static int match_hash(unsigned, const unsigned char *, const unsigned char *);

static enum cb_next match_prefix(const struct object_id *oid, void *arg)
{
	struct disambiguate_state *ds = arg;
	/* no need to call match_hash, oidtree_each did prefix match */
	update_candidates(ds, oid);
	return ds->ambiguous ? CB_BREAK : CB_CONTINUE;
}

static void find_short_object_filename(struct disambiguate_state *ds)
{
	struct odb_source *source;

	for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next)
		oidtree_each(odb_loose_cache(source, &ds->bin_pfx),
				&ds->bin_pfx, ds->len, match_prefix, ds);
}

static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
{
	do {
		if (*a != *b)
			return 0;
		a++;
		b++;
		len -= 2;
	} while (len > 1);
	if (len)
		if ((*a ^ *b) & 0xf0)
			return 0;
	return 1;
}

static void unique_in_midx(struct multi_pack_index *m,
			   struct disambiguate_state *ds)
{
	for (; m; m = m->base_midx) {
		uint32_t num, i, first = 0;
		const struct object_id *current = NULL;
		int len = ds->len > ds->repo->hash_algo->hexsz ?
			ds->repo->hash_algo->hexsz : ds->len;

		if (!m->num_objects)
			continue;

		num = m->num_objects + m->num_objects_in_base;

		bsearch_one_midx(&ds->bin_pfx, m, &first);

		/*
		 * At this point, "first" is the location of the lowest
		 * object with an object name that could match
		 * "bin_pfx".  See if we have 0, 1 or more objects that
		 * actually match(es).
		 */
		for (i = first; i < num && !ds->ambiguous; i++) {
			struct object_id oid;
			current = nth_midxed_object_oid(&oid, m, i);
			if (!match_hash(len, ds->bin_pfx.hash, current->hash))
				break;
			update_candidates(ds, current);
		}
	}
}

static void unique_in_pack(struct packed_git *p,
			   struct disambiguate_state *ds)
{
	uint32_t num, i, first = 0;
	int len = ds->len > ds->repo->hash_algo->hexsz ?
		ds->repo->hash_algo->hexsz : ds->len;

	if (p->multi_pack_index)
		return;

	if (open_pack_index(p) || !p->num_objects)
		return;

	num = p->num_objects;
	bsearch_pack(&ds->bin_pfx, p, &first);

	/*
	 * At this point, "first" is the location of the lowest object
	 * with an object name that could match "bin_pfx".  See if we have
	 * 0, 1 or more objects that actually match(es).
	 */
	for (i = first; i < num && !ds->ambiguous; i++) {
		struct object_id oid;
		nth_packed_object_id(&oid, p, i);
		if (!match_hash(len, ds->bin_pfx.hash, oid.hash))
			break;
		update_candidates(ds, &oid);
	}
}

static void find_short_packed_object(struct disambiguate_state *ds)
{
	struct odb_source *source;
	struct packed_git *p;

	/* Skip, unless oids from the storage hash algorithm are wanted */
	if (ds->bin_pfx.algo && (&hash_algos[ds->bin_pfx.algo] != ds->repo->hash_algo))
		return;

	odb_prepare_alternates(ds->repo->objects);
	for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next) {
		struct multi_pack_index *m = get_multi_pack_index(source);
		if (m)
			unique_in_midx(m, ds);
	}

	for (p = get_packed_git(ds->repo); p && !ds->ambiguous;
	     p = p->next)
		unique_in_pack(p, ds);
}

static int finish_object_disambiguation(struct disambiguate_state *ds,
					struct object_id *oid)
{
	if (ds->ambiguous)
		return SHORT_NAME_AMBIGUOUS;

	if (!ds->candidate_exists)
		return MISSING_OBJECT;

	if (!ds->candidate_checked)
		/*
		 * If this is the only candidate, there is no point
		 * calling the disambiguation hint callback.
		 *
		 * On the other hand, if the current candidate
		 * replaced an earlier candidate that did _not_ pass
		 * the disambiguation hint callback, then we do have
		 * more than one objects that match the short name
		 * given, so we should make sure this one matches;
		 * otherwise, if we discovered this one and the one
		 * that we previously discarded in the reverse order,
		 * we would end up showing different results in the
		 * same repository!
		 */
		ds->candidate_ok = (!ds->disambiguate_fn_used ||
				    ds->fn(ds->repo, &ds->candidate, ds->cb_data));

	if (!ds->candidate_ok)
		return SHORT_NAME_AMBIGUOUS;

	oidcpy(oid, &ds->candidate);
	return 0;
}

static int disambiguate_commit_only(struct repository *r,
				    const struct object_id *oid,
				    void *cb_data UNUSED)
{
	int kind = odb_read_object_info(r->objects, oid, NULL);
	return kind == OBJ_COMMIT;
}

static int disambiguate_committish_only(struct repository *r,
					const struct object_id *oid,
					void *cb_data UNUSED)
{
	struct object *obj;
	int kind;

	kind = odb_read_object_info(r->objects, oid, NULL);
	if (kind == OBJ_COMMIT)
		return 1;
	if (kind != OBJ_TAG)
		return 0;

	/* We need to do this the hard way... */
	obj = deref_tag(r, parse_object(r, oid), NULL, 0);
	if (obj && obj->type == OBJ_COMMIT)
		return 1;
	return 0;
}

static int disambiguate_tree_only(struct repository *r,
				  const struct object_id *oid,
				  void *cb_data UNUSED)
{
	int kind = odb_read_object_info(r->objects, oid, NULL);
	return kind == OBJ_TREE;
}

static int disambiguate_treeish_only(struct repository *r,
				     const struct object_id *oid,
				     void *cb_data UNUSED)
{
	struct object *obj;
	int kind;

	kind = odb_read_object_info(r->objects, oid, NULL);
	if (kind == OBJ_TREE || kind == OBJ_COMMIT)
		return 1;
	if (kind != OBJ_TAG)
		return 0;

	/* We need to do this the hard way... */
	obj = deref_tag(r, parse_object(r, oid), NULL, 0);
	if (obj && (obj->type == OBJ_TREE || obj->type == OBJ_COMMIT))
		return 1;
	return 0;
}

static int disambiguate_blob_only(struct repository *r,
				  const struct object_id *oid,
				  void *cb_data UNUSED)
{
	int kind = odb_read_object_info(r->objects, oid, NULL);
	return kind == OBJ_BLOB;
}

static disambiguate_hint_fn default_disambiguate_hint;

int set_disambiguate_hint_config(const char *var, const char *value)
{
	static const struct {
		const char *name;
		disambiguate_hint_fn fn;
	} hints[] = {
		{ "none", NULL },
		{ "commit", disambiguate_commit_only },
		{ "committish", disambiguate_committish_only },
		{ "tree", disambiguate_tree_only },
		{ "treeish", disambiguate_treeish_only },
		{ "blob", disambiguate_blob_only }
	};
	int i;

	if (!value)
		return config_error_nonbool(var);

	for (i = 0; i < ARRAY_SIZE(hints); i++) {
		if (!strcasecmp(value, hints[i].name)) {
			default_disambiguate_hint = hints[i].fn;
			return 0;
		}
	}

	return error("unknown hint type for '%s': %s", var, value);
}

static int init_object_disambiguation(struct repository *r,
				      const char *name, int len,
				      const struct git_hash_algo *algo,
				      struct disambiguate_state *ds)
{
	int i;

	if (len < MINIMUM_ABBREV || len > GIT_MAX_HEXSZ)
		return -1;

	memset(ds, 0, sizeof(*ds));

	for (i = 0; i < len ;i++) {
		unsigned char c = name[i];
		unsigned char val;
		if (c >= '0' && c <= '9')
			val = c - '0';
		else if (c >= 'a' && c <= 'f')
			val = c - 'a' + 10;
		else if (c >= 'A' && c <='F') {
			val = c - 'A' + 10;
			c -= 'A' - 'a';
		}
		else
			return -1;
		ds->hex_pfx[i] = c;
		if (!(i & 1))
			val <<= 4;
		ds->bin_pfx.hash[i >> 1] |= val;
	}

	ds->len = len;
	ds->hex_pfx[len] = '\0';
	ds->repo = r;
	ds->bin_pfx.algo = algo ? hash_algo_by_ptr(algo) : GIT_HASH_UNKNOWN;
	odb_prepare_alternates(r->objects);
	return 0;
}

struct ambiguous_output {
	const struct disambiguate_state *ds;
	struct strbuf advice;
	struct strbuf sb;
};

static int show_ambiguous_object(const struct object_id *oid, void *data)
{
	struct ambiguous_output *state = data;
	const struct disambiguate_state *ds = state->ds;
	struct strbuf *advice = &state->advice;
	struct strbuf *sb = &state->sb;
	int type;
	const char *hash;

	if (ds->fn && !ds->fn(ds->repo, oid, ds->cb_data))
		return 0;

	hash = repo_find_unique_abbrev(ds->repo, oid, DEFAULT_ABBREV);
	type = odb_read_object_info(ds->repo->objects, oid, NULL);

	if (type < 0) {
		/*
		 * TRANSLATORS: This is a line of ambiguous object
		 * output shown when we cannot look up or parse the
		 * object in question. E.g. "deadbeef [bad object]".
		 */
		strbuf_addf(sb, _("%s [bad object]"), hash);
		goto out;
	}

	assert(type == OBJ_TREE || type == OBJ_COMMIT ||
	       type == OBJ_BLOB || type == OBJ_TAG);

	if (type == OBJ_COMMIT) {
		struct strbuf date = STRBUF_INIT;
		struct strbuf msg = STRBUF_INIT;
		struct commit *commit = lookup_commit(ds->repo, oid);

		if (commit) {
			struct pretty_print_context pp = {0};
			pp.date_mode.type = DATE_SHORT;
			repo_format_commit_message(the_repository, commit,
						   "%ad", &date, &pp);
			repo_format_commit_message(the_repository, commit,
						   "%s", &msg, &pp);
		}

		/*
		 * TRANSLATORS: This is a line of ambiguous commit
		 * object output. E.g.:
		 *
		 *    "deadbeef commit 2021-01-01 - Some Commit Message"
		 */
		strbuf_addf(sb, _("%s commit %s - %s"), hash, date.buf,
			    msg.buf);

		strbuf_release(&date);
		strbuf_release(&msg);
	} else if (type == OBJ_TAG) {
		struct tag *tag = lookup_tag(ds->repo, oid);

		if (!parse_tag(tag) && tag->tag) {
			/*
			 * TRANSLATORS: This is a line of ambiguous
			 * tag object output. E.g.:
			 *
			 *    "deadbeef tag 2022-01-01 - Some Tag Message"
			 *
			 * The second argument is the YYYY-MM-DD found
			 * in the tag.
			 *
			 * The third argument is the "tag" string
			 * from object.c.
			 */
			strbuf_addf(sb, _("%s tag %s - %s"), hash,
				    show_date(tag->date, 0, DATE_MODE(SHORT)),
				    tag->tag);
		} else {
			/*
			 * TRANSLATORS: This is a line of ambiguous
			 * tag object output where we couldn't parse
			 * the tag itself. E.g.:
			 *
			 *    "deadbeef [bad tag, could not parse it]"
			 */
			strbuf_addf(sb, _("%s [bad tag, could not parse it]"),
				    hash);
		}
	} else if (type == OBJ_TREE) {
		/*
		 * TRANSLATORS: This is a line of ambiguous <type>
		 * object output. E.g. "deadbeef tree".
		 */
		strbuf_addf(sb, _("%s tree"), hash);
	} else if (type == OBJ_BLOB) {
		/*
		 * TRANSLATORS: This is a line of ambiguous <type>
		 * object output. E.g. "deadbeef blob".
		 */
		strbuf_addf(sb, _("%s blob"), hash);
	}


out:
	/*
	 * TRANSLATORS: This is line item of ambiguous object output
	 * from describe_ambiguous_object() above. For RTL languages
	 * you'll probably want to swap the "%s" and leading " " space
	 * around.
	 */
	strbuf_addf(advice, _("  %s\n"), sb->buf);

	strbuf_reset(sb);
	return 0;
}

static int collect_ambiguous(const struct object_id *oid, void *data)
{
	oid_array_append(data, oid);
	return 0;
}

static int repo_collect_ambiguous(struct repository *r UNUSED,
				  const struct object_id *oid,
				  void *data)
{
	return collect_ambiguous(oid, data);
}

static int sort_ambiguous(const void *va, const void *vb, void *ctx)
{
	struct repository *sort_ambiguous_repo = ctx;
	const struct object_id *a = va, *b = vb;
	int a_type = odb_read_object_info(sort_ambiguous_repo->objects, a, NULL);
	int b_type = odb_read_object_info(sort_ambiguous_repo->objects, b, NULL);
	int a_type_sort;
	int b_type_sort;

	/*
	 * Sorts by hash within the same object type, just as
	 * oid_array_for_each_unique() would do.
	 */
	if (a_type == b_type) {
		if (a->algo == b->algo)
			return oidcmp(a, b);
		else
			return a->algo > b->algo ? 1 : -1;
	}

	/*
	 * Between object types show tags, then commits, and finally
	 * trees and blobs.
	 *
	 * The object_type enum is commit, tree, blob, tag, but we
	 * want tag, commit, tree blob. Cleverly (perhaps too
	 * cleverly) do that with modulus, since the enum assigns 1 to
	 * commit, so tag becomes 0.
	 */
	a_type_sort = a_type % 4;
	b_type_sort = b_type % 4;
	return a_type_sort > b_type_sort ? 1 : -1;
}

static void sort_ambiguous_oid_array(struct repository *r, struct oid_array *a)
{
	QSORT_S(a->oid, a->nr, sort_ambiguous, r);
}

static enum get_oid_result get_short_oid(struct repository *r,
					 const char *name, int len,
					 struct object_id *oid,
					 unsigned flags)
{
	int status;
	struct disambiguate_state ds;
	int quietly = !!(flags & GET_OID_QUIETLY);
	const struct git_hash_algo *algo = r->hash_algo;

	if (flags & GET_OID_HASH_ANY)
		algo = NULL;

	if (init_object_disambiguation(r, name, len, algo, &ds) < 0)
		return -1;

	if (HAS_MULTI_BITS(flags & GET_OID_DISAMBIGUATORS))
		BUG("multiple get_short_oid disambiguator flags");

	if (flags & GET_OID_COMMIT)
		ds.fn = disambiguate_commit_only;
	else if (flags & GET_OID_COMMITTISH)
		ds.fn = disambiguate_committish_only;
	else if (flags & GET_OID_TREE)
		ds.fn = disambiguate_tree_only;
	else if (flags & GET_OID_TREEISH)
		ds.fn = disambiguate_treeish_only;
	else if (flags & GET_OID_BLOB)
		ds.fn = disambiguate_blob_only;
	else
		ds.fn = default_disambiguate_hint;

	find_short_object_filename(&ds);
	find_short_packed_object(&ds);
	status = finish_object_disambiguation(&ds, oid);

	/*
	 * If we didn't find it, do the usual reprepare() slow-path,
	 * since the object may have recently been added to the repository
	 * or migrated from loose to packed.
	 */
	if (status == MISSING_OBJECT) {
		reprepare_packed_git(r);
		find_short_object_filename(&ds);
		find_short_packed_object(&ds);
		status = finish_object_disambiguation(&ds, oid);
	}

	if (!quietly && (status == SHORT_NAME_AMBIGUOUS)) {
		struct oid_array collect = OID_ARRAY_INIT;
		struct ambiguous_output out = {
			.ds = &ds,
			.sb = STRBUF_INIT,
			.advice = STRBUF_INIT,
		};

		error(_("short object ID %s is ambiguous"), ds.hex_pfx);

		/*
		 * We may still have ambiguity if we simply saw a series of
		 * candidates that did not satisfy our hint function. In
		 * that case, we still want to show them, so disable the hint
		 * function entirely.
		 */
		if (!ds.ambiguous)
			ds.fn = NULL;

		repo_for_each_abbrev(r, ds.hex_pfx, algo, collect_ambiguous, &collect);
		sort_ambiguous_oid_array(r, &collect);

		if (oid_array_for_each(&collect, show_ambiguous_object, &out))
			BUG("show_ambiguous_object shouldn't return non-zero");

		/*
		 * TRANSLATORS: The argument is the list of ambiguous
		 * objects composed in show_ambiguous_object(). See
		 * its "TRANSLATORS" comments for details.
		 */
		advise(_("The candidates are:\n%s"), out.advice.buf);

		oid_array_clear(&collect);
		strbuf_release(&out.advice);
		strbuf_release(&out.sb);
	}

	return status;
}

int repo_for_each_abbrev(struct repository *r, const char *prefix,
			 const struct git_hash_algo *algo,
			 each_abbrev_fn fn, void *cb_data)
{
	struct oid_array collect = OID_ARRAY_INIT;
	struct disambiguate_state ds;
	int ret;

	if (init_object_disambiguation(r, prefix, strlen(prefix), algo, &ds) < 0)
		return -1;

	ds.always_call_fn = 1;
	ds.fn = repo_collect_ambiguous;
	ds.cb_data = &collect;
	find_short_object_filename(&ds);
	find_short_packed_object(&ds);

	ret = oid_array_for_each_unique(&collect, fn, cb_data);
	oid_array_clear(&collect);
	return ret;
}

/*
 * Return the slot of the most-significant bit set in "val". There are various
 * ways to do this quickly with fls() or __builtin_clzl(), but speed is
 * probably not a big deal here.
 */
static unsigned msb(unsigned long val)
{
	unsigned r = 0;
	while (val >>= 1)
		r++;
	return r;
}

struct min_abbrev_data {
	unsigned int init_len;
	unsigned int cur_len;
	char *hex;
	struct repository *repo;
	const struct object_id *oid;
};

static inline char get_hex_char_from_oid(const struct object_id *oid,
					 unsigned int pos)
{
	static const char hex[] = "0123456789abcdef";

	if ((pos & 1) == 0)
		return hex[oid->hash[pos >> 1] >> 4];
	else
		return hex[oid->hash[pos >> 1] & 0xf];
}

static int extend_abbrev_len(const struct object_id *oid,
			     struct min_abbrev_data *mad)
{
	unsigned int i = mad->init_len;
	while (mad->hex[i] && mad->hex[i] == get_hex_char_from_oid(oid, i))
		i++;

	if (i < GIT_MAX_RAWSZ && i >= mad->cur_len)
		mad->cur_len = i + 1;

	return 0;
}

static int repo_extend_abbrev_len(struct repository *r UNUSED,
				  const struct object_id *oid,
				  void *cb_data)
{
	return extend_abbrev_len(oid, cb_data);
}

static void find_abbrev_len_for_midx(struct multi_pack_index *m,
				     struct min_abbrev_data *mad)
{
	for (; m; m = m->base_midx) {
		int match = 0;
		uint32_t num, first = 0;
		struct object_id oid;
		const struct object_id *mad_oid;

		if (!m->num_objects)
			continue;

		num = m->num_objects + m->num_objects_in_base;
		mad_oid = mad->oid;
		match = bsearch_one_midx(mad_oid, m, &first);

		/*
		 * first is now the position in the packfile where we
		 * would insert mad->hash if it does not exist (or the
		 * position of mad->hash if it does exist). Hence, we
		 * consider a maximum of two objects nearby for the
		 * abbreviation length.
		 */
		mad->init_len = 0;
		if (!match) {
			if (nth_midxed_object_oid(&oid, m, first))
				extend_abbrev_len(&oid, mad);
		} else if (first < num - 1) {
			if (nth_midxed_object_oid(&oid, m, first + 1))
				extend_abbrev_len(&oid, mad);
		}
		if (first > 0) {
			if (nth_midxed_object_oid(&oid, m, first - 1))
				extend_abbrev_len(&oid, mad);
		}
		mad->init_len = mad->cur_len;
	}
}

static void find_abbrev_len_for_pack(struct packed_git *p,
				     struct min_abbrev_data *mad)
{
	int match = 0;
	uint32_t num, first = 0;
	struct object_id oid;
	const struct object_id *mad_oid;

	if (p->multi_pack_index)
		return;

	if (open_pack_index(p) || !p->num_objects)
		return;

	num = p->num_objects;
	mad_oid = mad->oid;
	match = bsearch_pack(mad_oid, p, &first);

	/*
	 * first is now the position in the packfile where we would insert
	 * mad->hash if it does not exist (or the position of mad->hash if
	 * it does exist). Hence, we consider a maximum of two objects
	 * nearby for the abbreviation length.
	 */
	mad->init_len = 0;
	if (!match) {
		if (!nth_packed_object_id(&oid, p, first))
			extend_abbrev_len(&oid, mad);
	} else if (first < num - 1) {
		if (!nth_packed_object_id(&oid, p, first + 1))
			extend_abbrev_len(&oid, mad);
	}
	if (first > 0) {
		if (!nth_packed_object_id(&oid, p, first - 1))
			extend_abbrev_len(&oid, mad);
	}
	mad->init_len = mad->cur_len;
}

static void find_abbrev_len_packed(struct min_abbrev_data *mad)
{
	struct packed_git *p;

	odb_prepare_alternates(mad->repo->objects);
	for (struct odb_source *source = mad->repo->objects->sources; source; source = source->next) {
		struct multi_pack_index *m = get_multi_pack_index(source);
		if (m)
			find_abbrev_len_for_midx(m, mad);
	}

	for (p = get_packed_git(mad->repo); p; p = p->next)
		find_abbrev_len_for_pack(p, mad);
}

void strbuf_repo_add_unique_abbrev(struct strbuf *sb, struct repository *repo,
				   const struct object_id *oid, int abbrev_len)
{
	int r;
	strbuf_grow(sb, GIT_MAX_HEXSZ + 1);
	r = repo_find_unique_abbrev_r(repo, sb->buf + sb->len, oid, abbrev_len);
	strbuf_setlen(sb, sb->len + r);
}

void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid,
			      int abbrev_len)
{
	strbuf_repo_add_unique_abbrev(sb, the_repository, oid, abbrev_len);
}

int repo_find_unique_abbrev_r(struct repository *r, char *hex,
			      const struct object_id *oid, int len)
{
	const struct git_hash_algo *algo =
		oid->algo ? &hash_algos[oid->algo] : r->hash_algo;
	struct disambiguate_state ds;
	struct min_abbrev_data mad;
	struct object_id oid_ret;
	const unsigned hexsz = algo->hexsz;

	if (len < 0) {
		unsigned long count = repo_approximate_object_count(r);
		/*
		 * Add one because the MSB only tells us the highest bit set,
		 * not including the value of all the _other_ bits (so "15"
		 * is only one off of 2^4, but the MSB is the 3rd bit.
		 */
		len = msb(count) + 1;
		/*
		 * We now know we have on the order of 2^len objects, which
		 * expects a collision at 2^(len/2). But we also care about hex
		 * chars, not bits, and there are 4 bits per hex. So all
		 * together we need to divide by 2 and round up.
		 */
		len = DIV_ROUND_UP(len, 2);
		/*
		 * For very small repos, we stick with our regular fallback.
		 */
		if (len < FALLBACK_DEFAULT_ABBREV)
			len = FALLBACK_DEFAULT_ABBREV;
	}

	oid_to_hex_r(hex, oid);
	if (len >= hexsz || !len)
		return hexsz;

	mad.repo = r;
	mad.init_len = len;
	mad.cur_len = len;
	mad.hex = hex;
	mad.oid = oid;

	find_abbrev_len_packed(&mad);

	if (init_object_disambiguation(r, hex, mad.cur_len, algo, &ds) < 0)
		return -1;

	ds.fn = repo_extend_abbrev_len;
	ds.always_call_fn = 1;
	ds.cb_data = (void *)&mad;

	find_short_object_filename(&ds);
	(void)finish_object_disambiguation(&ds, &oid_ret);

	hex[mad.cur_len] = 0;
	return mad.cur_len;
}

const char *repo_find_unique_abbrev(struct repository *r,
				    const struct object_id *oid,
				    int len)
{
	static int bufno;
	static char hexbuffer[4][GIT_MAX_HEXSZ + 1];
	char *hex = hexbuffer[bufno];
	bufno = (bufno + 1) % ARRAY_SIZE(hexbuffer);
	repo_find_unique_abbrev_r(r, hex, oid, len);
	return hex;
}

static int ambiguous_path(const char *path, int len)
{
	int slash = 1;
	int cnt;

	for (cnt = 0; cnt < len; cnt++) {
		switch (*path++) {
		case '\0':
			break;
		case '/':
			if (slash)
				break;
			slash = 1;
			continue;
		case '.':
			continue;
		default:
			slash = 0;
			continue;
		}
		break;
	}
	return slash;
}

static inline int at_mark(const char *string, int len,
			  const char **suffix, int nr)
{
	int i;

	for (i = 0; i < nr; i++) {
		int suffix_len = strlen(suffix[i]);
		if (suffix_len <= len
		    && !strncasecmp(string, suffix[i], suffix_len))
			return suffix_len;
	}
	return 0;
}

static inline int upstream_mark(const char *string, int len)
{
	const char *suffix[] = { "@{upstream}", "@{u}" };
	return at_mark(string, len, suffix, ARRAY_SIZE(suffix));
}

static inline int push_mark(const char *string, int len)
{
	const char *suffix[] = { "@{push}" };
	return at_mark(string, len, suffix, ARRAY_SIZE(suffix));
}

static enum get_oid_result get_oid_1(struct repository *r, const char *name, int len, struct object_id *oid, unsigned lookup_flags);
static int interpret_nth_prior_checkout(struct repository *r, const char *name, int namelen, struct strbuf *buf);

static int get_oid_basic(struct repository *r, const char *str, int len,
			 struct object_id *oid, unsigned int flags)
{
	static const char *warn_msg = "refname '%.*s' is ambiguous.";
	static const char *object_name_msg = N_(
	"Git normally never creates a ref that ends with 40 hex characters\n"
	"because it will be ignored when you just specify 40-hex. These refs\n"
	"may be created by mistake. For example,\n"
	"\n"
	"  git switch -c $br $(git rev-parse ...)\n"
	"\n"
	"where \"$br\" is somehow empty and a 40-hex ref is created. Please\n"
	"examine these refs and maybe delete them. Turn this message off by\n"
	"running \"git config set advice.objectNameWarning false\"");
	struct object_id tmp_oid;
	char *real_ref = NULL;
	int refs_found = 0;
	int at, reflog_len, nth_prior = 0;
	int fatal = !(flags & GET_OID_QUIETLY);

	if (len == r->hash_algo->hexsz && !get_oid_hex(str, oid)) {
		if (!(flags & GET_OID_SKIP_AMBIGUITY_CHECK) &&
		    repo_settings_get_warn_ambiguous_refs(r) &&
		    warn_on_object_refname_ambiguity) {
			refs_found = repo_dwim_ref(r, str, len, &tmp_oid, &real_ref, 0);
			if (refs_found > 0) {
				warning(warn_msg, len, str);
				if (advice_enabled(ADVICE_OBJECT_NAME_WARNING))
					fprintf(stderr, "%s\n", _(object_name_msg));
			}
			free(real_ref);
		}
		return 0;
	}

	/* basic@{time or number or -number} format to query ref-log */
	reflog_len = at = 0;
	if (len && str[len-1] == '}') {
		for (at = len-4; at >= 0; at--) {
			if (str[at] == '@' && str[at+1] == '{') {
				if (str[at+2] == '-') {
					if (at != 0)
						/* @{-N} not at start */
						return -1;
					nth_prior = 1;
					continue;
				}
				if (!upstream_mark(str + at, len - at) &&
				    !push_mark(str + at, len - at)) {
					reflog_len = (len-1) - (at+2);
					len = at;
				}
				break;
			}
		}
	}

	/* Accept only unambiguous ref paths. */
	if (len && ambiguous_path(str, len))
		return -1;

	if (nth_prior) {
		struct strbuf buf = STRBUF_INIT;
		int detached;

		if (interpret_nth_prior_checkout(r, str, len, &buf) > 0) {
			detached = (buf.len == r->hash_algo->hexsz && !get_oid_hex(buf.buf, oid));
			strbuf_release(&buf);
			if (detached)
				return 0;
		}
	}

	if (!len && reflog_len)
		/* allow "@{...}" to mean the current branch reflog */
		refs_found = repo_dwim_ref(r, "HEAD", 4, oid, &real_ref, !fatal);
	else if (reflog_len)
		refs_found = repo_dwim_log(r, str, len, oid, &real_ref);
	else
		refs_found = repo_dwim_ref(r, str, len, oid, &real_ref, !fatal);

	if (!refs_found)
		return -1;

	if (repo_settings_get_warn_ambiguous_refs(r) && !(flags & GET_OID_QUIETLY) &&
	    (refs_found > 1 ||
	     !get_short_oid(r, str, len, &tmp_oid, GET_OID_QUIETLY)))
		warning(warn_msg, len, str);

	if (reflog_len) {
		int nth, i;
		timestamp_t at_time;
		timestamp_t co_time;
		int co_tz, co_cnt;

		/* Is it asking for N-th entry, or approxidate? */
		for (i = nth = 0; 0 <= nth && i < reflog_len; i++) {
			char ch = str[at+2+i];
			if ('0' <= ch && ch <= '9')
				nth = nth * 10 + ch - '0';
			else
				nth = -1;
		}
		if (100000000 <= nth) {
			at_time = nth;
			nth = -1;
		} else if (0 <= nth)
			at_time = 0;
		else {
			int errors = 0;
			char *tmp = xstrndup(str + at + 2, reflog_len);
			at_time = approxidate_careful(tmp, &errors);
			free(tmp);
			if (errors) {
				free(real_ref);
				return -1;
			}
		}
		if (read_ref_at(get_main_ref_store(r),
				real_ref, flags, at_time, nth, oid, NULL,
				&co_time, &co_tz, &co_cnt)) {
			if (!len) {
				if (!skip_prefix(real_ref, "refs/heads/", &str))
					str = "HEAD";
				len = strlen(str);
			}
			if (at_time) {
				if (!(flags & GET_OID_QUIETLY)) {
					warning(_("log for '%.*s' only goes back to %s"),
						len, str,
						show_date(co_time, co_tz, DATE_MODE(RFC2822)));
				}
			} else if (nth == co_cnt && !is_null_oid(oid)) {
				/*
				 * We were asked for the Nth reflog (counting
				 * from 0), but there were only N entries.
				 * read_ref_at() will have returned "1" to tell
				 * us it did not find an entry, but it did
				 * still fill in the oid with the "old" value,
				 * which we can use.
				 */
			} else if (!(flags & GET_OID_GENTLY)) {
				if (flags & GET_OID_QUIETLY) {
					exit(128);
				}
				die(_("log for '%.*s' only has %d entries"),
				    len, str, co_cnt);
			}
			if (flags & GET_OID_GENTLY) {
				free(real_ref);
				return -1;
			}
		}
	}

	free(real_ref);
	return 0;
}

static enum get_oid_result get_parent(struct repository *r,
				      const char *name, int len,
				      struct object_id *result, int idx)
{
	struct object_id oid;
	enum get_oid_result ret = get_oid_1(r, name, len, &oid,
					    GET_OID_COMMITTISH);
	struct commit *commit;
	struct commit_list *p;

	if (ret)
		return ret;
	commit = lookup_commit_reference(r, &oid);
	if (repo_parse_commit(r, commit))
		return MISSING_OBJECT;
	if (!idx) {
		oidcpy(result, &commit->object.oid);
		return FOUND;
	}
	p = commit->parents;
	while (p) {
		if (!--idx) {
			oidcpy(result, &p->item->object.oid);
			return FOUND;
		}
		p = p->next;
	}
	return MISSING_OBJECT;
}

static enum get_oid_result get_nth_ancestor(struct repository *r,
					    const char *name, int len,
					    struct object_id *result,
					    int generation)
{
	struct object_id oid;
	struct commit *commit;
	int ret;

	ret = get_oid_1(r, name, len, &oid, GET_OID_COMMITTISH);
	if (ret)
		return ret;
	commit = lookup_commit_reference(r, &oid);
	if (!commit)
		return MISSING_OBJECT;

	while (generation--) {
		if (repo_parse_commit(r, commit) || !commit->parents)
			return MISSING_OBJECT;
		commit = commit->parents->item;
	}
	oidcpy(result, &commit->object.oid);
	return FOUND;
}

struct object *repo_peel_to_type(struct repository *r, const char *name, int namelen,
				 struct object *o, enum object_type expected_type)
{
	if (name && !namelen)
		namelen = strlen(name);
	while (1) {
		if (!o || (!o->parsed && !parse_object(r, &o->oid)))
			return NULL;
		if (expected_type == OBJ_ANY || o->type == expected_type)
			return o;
		if (o->type == OBJ_TAG)
			o = ((struct tag*) o)->tagged;
		else if (o->type == OBJ_COMMIT)
			o = &(repo_get_commit_tree(r, ((struct commit *)o))->object);
		else {
			if (name)
				error("%.*s: expected %s type, but the object "
				      "dereferences to %s type",
				      namelen, name, type_name(expected_type),
				      type_name(o->type));
			return NULL;
		}
	}
}

static int peel_onion(struct repository *r, const char *name, int len,
		      struct object_id *oid, unsigned lookup_flags)
{
	struct object_id outer;
	const char *sp;
	unsigned int expected_type = 0;
	struct object *o;

	/*
	 * "ref^{type}" dereferences ref repeatedly until you cannot
	 * dereference anymore, or you get an object of given type,
	 * whichever comes first.  "ref^{}" means just dereference
	 * tags until you get a non-tag.  "ref^0" is a shorthand for
	 * "ref^{commit}".  "commit^{tree}" could be used to find the
	 * top-level tree of the given commit.
	 */
	if (len < 4 || name[len-1] != '}')
		return -1;

	for (sp = name + len - 1; name <= sp; sp--) {
		int ch = *sp;
		if (ch == '{' && name < sp && sp[-1] == '^')
			break;
	}
	if (sp <= name)
		return -1;

	sp++; /* beginning of type name, or closing brace for empty */
	if (starts_with(sp, "commit}"))
		expected_type = OBJ_COMMIT;
	else if (starts_with(sp, "tag}"))
		expected_type = OBJ_TAG;
	else if (starts_with(sp, "tree}"))
		expected_type = OBJ_TREE;
	else if (starts_with(sp, "blob}"))
		expected_type = OBJ_BLOB;
	else if (starts_with(sp, "object}"))
		expected_type = OBJ_ANY;
	else if (sp[0] == '}')
		expected_type = OBJ_NONE;
	else if (sp[0] == '/')
		expected_type = OBJ_COMMIT;
	else
		return -1;

	lookup_flags &= ~GET_OID_DISAMBIGUATORS;
	if (expected_type == OBJ_COMMIT)
		lookup_flags |= GET_OID_COMMITTISH;
	else if (expected_type == OBJ_TREE)
		lookup_flags |= GET_OID_TREEISH;

	if (get_oid_1(r, name, sp - name - 2, &outer, lookup_flags))
		return -1;

	o = parse_object(r, &outer);
	if (!o)
		return -1;
	if (!expected_type) {
		o = deref_tag(r, o, name, sp - name - 2);
		if (!o || (!o->parsed && !parse_object(r, &o->oid)))
			return -1;
		oidcpy(oid, &o->oid);
		return 0;
	}

	/*
	 * At this point, the syntax look correct, so
	 * if we do not get the needed object, we should
	 * barf.
	 */
	o = repo_peel_to_type(r, name, len, o, expected_type);
	if (!o)
		return -1;

	oidcpy(oid, &o->oid);
	if (sp[0] == '/') {
		/* "$commit^{/foo}" */
		char *prefix;
		int ret;
		struct commit_list *list = NULL;

		/*
		 * $commit^{/}. Some regex implementation may reject.
		 * We don't need regex anyway. '' pattern always matches.
		 */
		if (sp[1] == '}')
			return 0;

		prefix = xstrndup(sp + 1, name + len - 1 - (sp + 1));
		commit_list_insert((struct commit *)o, &list);
		ret = get_oid_oneline(r, prefix, oid, list);

		free_commit_list(list);
		free(prefix);
		return ret;
	}
	return 0;
}

/*
 * Documentation/revisions.adoc says:
 *    '<describeOutput>', e.g. 'v1.7.4.2-679-g3bee7fb'::
 *      Output from `git describe`; i.e. a closest tag, optionally
 *      followed by a dash and a number of commits, followed by a dash, a
 *      'g', and an abbreviated object name.
 *
 * which means that the stuff before '-g${HASH}' needs to be a valid
 * refname, a dash, and a non-negative integer.  This function verifies
 * that.
 *
 * In particular, we do not want to treat
 *   branchname:path/to/file/named/i-gaffed
 * as a request for commit affed.
 *
 * More generally, we should probably not treat
 *   'refs/heads/./../.../ ~^:/?*[////\\\&}/busted.lock-g050e0ef6ead'
 * as a request for object 050e0ef6ead either.
 *
 * We are called with name[len] == '-' and name[len+1] == 'g', i.e.
 * we are verifying ${REFNAME}-{INTEGER} part of the name.
 */
static int ref_and_count_parts_valid(const char *name, int len)
{
	struct strbuf sb;
	const char *cp;
	int flags = REFNAME_ALLOW_ONELEVEL;
	int ret = 1;

	/* Ensure we have at least one digit */
	if (!isxdigit(name[len-1]))
		return 0;

	/* Skip over digits backwards until we get to the dash */
	for (cp = name + len - 2; name < cp; cp--) {
		if (*cp == '-')
			break;
		if (!isxdigit(*cp))
			return 0;
	}
	/* Ensure we found the leading dash */
	if (*cp != '-')
		return 0;

	len = cp - name;
	strbuf_init(&sb, len);
	strbuf_add(&sb, name, len);
	ret = !check_refname_format(sb.buf, flags);
	strbuf_release(&sb);
	return ret;
}

static int get_describe_name(struct repository *r,
			     const char *name, int len,
			     struct object_id *oid)
{
	const char *cp;
	unsigned flags = GET_OID_QUIETLY | GET_OID_COMMIT;

	for (cp = name + len - 1; name + 2 <= cp; cp--) {
		char ch = *cp;
		if (!isxdigit(ch)) {
			/* We must be looking at g in "SOMETHING-g"
			 * for it to be describe output.
			 */
			if (ch == 'g' && cp[-1] == '-' &&
			    ref_and_count_parts_valid(name, cp - 1 - name)) {
				cp++;
				len -= cp - name;
				return get_short_oid(r,
						     cp, len, oid, flags);
			}
		}
	}
	return -1;
}

static enum get_oid_result get_oid_1(struct repository *r,
				     const char *name, int len,
				     struct object_id *oid,
				     unsigned lookup_flags)
{
	int ret, has_suffix;
	const char *cp;

	/*
	 * "name~3" is "name^^^", "name~" is "name~1", and "name^" is "name^1".
	 */
	has_suffix = 0;
	for (cp = name + len - 1; name <= cp; cp--) {
		int ch = *cp;
		if ('0' <= ch && ch <= '9')
			continue;
		if (ch == '~' || ch == '^')
			has_suffix = ch;
		break;
	}

	if (has_suffix) {
		unsigned int num = 0;
		int len1 = cp - name;
		cp++;
		while (cp < name + len) {
			unsigned int digit = *cp++ - '0';
			if (unsigned_mult_overflows(num, 10))
				return MISSING_OBJECT;
			num *= 10;
			if (unsigned_add_overflows(num, digit))
				return MISSING_OBJECT;
			num += digit;
		}
		if (!num && len1 == len - 1)
			num = 1;
		else if (num > INT_MAX)
			return MISSING_OBJECT;
		if (has_suffix == '^')
			return get_parent(r, name, len1, oid, num);
		/* else if (has_suffix == '~') -- goes without saying */
		return get_nth_ancestor(r, name, len1, oid, num);
	}

	ret = peel_onion(r, name, len, oid, lookup_flags);
	if (!ret)
		return FOUND;

	ret = get_oid_basic(r, name, len, oid, lookup_flags);
	if (!ret)
		return FOUND;

	/* It could be describe output that is "SOMETHING-gXXXX" */
	ret = get_describe_name(r, name, len, oid);
	if (!ret)
		return FOUND;

	return get_short_oid(r, name, len, oid, lookup_flags);
}

/*
 * This interprets names like ':/Initial revision of "git"' by searching
 * through history and returning the first commit whose message starts
 * the given regular expression.
 *
 * For negative-matching, prefix the pattern-part with '!-', like: ':/!-WIP'.
 *
 * For a literal '!' character at the beginning of a pattern, you have to repeat
 * that, like: ':/!!foo'
 *
 * For future extension, all other sequences beginning with ':/!' are reserved.
 */

/* Remember to update object flag allocation in object.h */
#define ONELINE_SEEN (1u<<20)

struct handle_one_ref_cb {
	struct repository *repo;
	struct commit_list **list;
};

static int handle_one_ref(const char *path, const char *referent UNUSED, const struct object_id *oid,
			  int flag UNUSED,
			  void *cb_data)
{
	struct handle_one_ref_cb *cb = cb_data;
	struct commit_list **list = cb->list;
	struct object *object = parse_object(cb->repo, oid);
	if (!object)
		return 0;
	if (object->type == OBJ_TAG) {
		object = deref_tag(cb->repo, object, path,
				   strlen(path));
		if (!object)
			return 0;
	}
	if (object->type != OBJ_COMMIT)
		return 0;
	commit_list_insert((struct commit *)object, list);
	return 0;
}

static int get_oid_oneline(struct repository *r,
			   const char *prefix, struct object_id *oid,
			   const struct commit_list *list)
{
	struct prio_queue copy = { compare_commits_by_commit_date };
	const struct commit_list *l;
	int found = 0;
	int negative = 0;
	regex_t regex;

	if (prefix[0] == '!') {
		prefix++;

		if (prefix[0] == '-') {
			prefix++;
			negative = 1;
		} else if (prefix[0] != '!') {
			return -1;
		}
	}

	if (regcomp(&regex, prefix, REG_EXTENDED))
		return -1;

	for (l = list; l; l = l->next) {
		l->item->object.flags |= ONELINE_SEEN;
		prio_queue_put(&copy, l->item);
	}
	while (copy.nr) {
		const char *p, *buf;
		struct commit *commit;
		int matches;

		commit = pop_most_recent_commit(&copy, ONELINE_SEEN);
		if (!parse_object(r, &commit->object.oid))
			continue;
		buf = repo_get_commit_buffer(r, commit, NULL);
		p = strstr(buf, "\n\n");
		matches = negative ^ (p && !regexec(&regex, p + 2, 0, NULL, 0));
		repo_unuse_commit_buffer(r, commit, buf);

		if (matches) {
			oidcpy(oid, &commit->object.oid);
			found = 1;
			break;
		}
	}
	regfree(&regex);
	for (l = list; l; l = l->next)
		clear_commit_marks(l->item, ONELINE_SEEN);
	clear_prio_queue(&copy);
	return found ? 0 : -1;
}

struct grab_nth_branch_switch_cbdata {
	int remaining;
	struct strbuf *sb;
};

static int grab_nth_branch_switch(const char *refname UNUSED,
				  struct object_id *ooid UNUSED,
				  struct object_id *noid UNUSED,
				  const char *email UNUSED,
				  timestamp_t timestamp UNUSED,
				  int tz UNUSED,
				  const char *message, void *cb_data)
{
	struct grab_nth_branch_switch_cbdata *cb = cb_data;
	const char *match = NULL, *target = NULL;
	size_t len;

	if (skip_prefix(message, "checkout: moving from ", &match))
		target = strstr(match, " to ");

	if (!match || !target)
		return 0;
	if (--(cb->remaining) == 0) {
		len = target - match;
		strbuf_reset(cb->sb);
		strbuf_add(cb->sb, match, len);
		return 1; /* we are done */
	}
	return 0;
}

/*
 * Parse @{-N} syntax, return the number of characters parsed
 * if successful; otherwise signal an error with negative value.
 */
static int interpret_nth_prior_checkout(struct repository *r,
					const char *name, int namelen,
					struct strbuf *buf)
{
	long nth;
	int retval;
	struct grab_nth_branch_switch_cbdata cb;
	const char *brace;
	char *num_end;

	if (namelen < 4)
		return -1;
	if (name[0] != '@' || name[1] != '{' || name[2] != '-')
		return -1;
	brace = memchr(name, '}', namelen);
	if (!brace)
		return -1;
	nth = strtol(name + 3, &num_end, 10);
	if (num_end != brace)
		return -1;
	if (nth <= 0)
		return -1;
	cb.remaining = nth;
	cb.sb = buf;

	retval = refs_for_each_reflog_ent_reverse(get_main_ref_store(r),
			"HEAD", grab_nth_branch_switch, &cb);
	if (0 < retval) {
		retval = brace - name + 1;
	} else
		retval = 0;

	return retval;
}

int repo_get_oid_mb(struct repository *r,
		    const char *name,
		    struct object_id *oid)
{
	struct commit *one, *two;
	struct commit_list *mbs = NULL;
	struct object_id oid_tmp;
	const char *dots;
	int st;

	dots = strstr(name, "...");
	if (!dots)
		return repo_get_oid(r, name, oid);
	if (dots == name)
		st = repo_get_oid(r, "HEAD", &oid_tmp);
	else {
		struct strbuf sb;
		strbuf_init(&sb, dots - name);
		strbuf_add(&sb, name, dots - name);
		st = repo_get_oid_committish(r, sb.buf, &oid_tmp);
		strbuf_release(&sb);
	}
	if (st)
		return st;
	one = lookup_commit_reference_gently(r, &oid_tmp, 0);
	if (!one)
		return -1;

	if (repo_get_oid_committish(r, dots[3] ? (dots + 3) : "HEAD", &oid_tmp))
		return -1;
	two = lookup_commit_reference_gently(r, &oid_tmp, 0);
	if (!two)
		return -1;
	if (repo_get_merge_bases(r, one, two, &mbs) < 0) {
		free_commit_list(mbs);
		return -1;
	}
	if (!mbs || mbs->next)
		st = -1;
	else {
		st = 0;
		oidcpy(oid, &mbs->item->object.oid);
	}
	free_commit_list(mbs);
	return st;
}

/* parse @something syntax, when 'something' is not {.*} */
static int interpret_empty_at(const char *name, int namelen, int len, struct strbuf *buf)
{
	const char *next;

	if (len || name[1] == '{')
		return -1;

	/* make sure it's a single @, or @@{.*}, not @foo */
	next = memchr(name + len + 1, '@', namelen - len - 1);
	if (next && next[1] != '{')
		return -1;
	if (!next)
		next = name + namelen;
	if (next != name + 1)
		return -1;

	strbuf_reset(buf);
	strbuf_add(buf, "HEAD", 4);
	return 1;
}

static int reinterpret(struct repository *r,
		       const char *name, int namelen, int len,
		       struct strbuf *buf, unsigned allowed)
{
	/* we have extra data, which might need further processing */
	struct strbuf tmp = STRBUF_INIT;
	int used = buf->len;
	int ret;
	struct interpret_branch_name_options options = {
		.allowed = allowed
	};

	strbuf_add(buf, name + len, namelen - len);
	ret = repo_interpret_branch_name(r, buf->buf, buf->len, &tmp, &options);
	/* that data was not interpreted, remove our cruft */
	if (ret < 0) {
		strbuf_setlen(buf, used);
		return len;
	}
	strbuf_reset(buf);
	strbuf_addbuf(buf, &tmp);
	strbuf_release(&tmp);
	/* tweak for size of {-N} versus expanded ref name */
	return ret - used + len;
}

static void set_shortened_ref(struct repository *r, struct strbuf *buf, const char *ref)
{
	char *s = refs_shorten_unambiguous_ref(get_main_ref_store(r), ref, 0);
	strbuf_reset(buf);
	strbuf_addstr(buf, s);
	free(s);
}

static int branch_interpret_allowed(const char *refname, unsigned allowed)
{
	if (!allowed)
		return 1;

	if ((allowed & INTERPRET_BRANCH_LOCAL) &&
	    starts_with(refname, "refs/heads/"))
		return 1;
	if ((allowed & INTERPRET_BRANCH_REMOTE) &&
	    starts_with(refname, "refs/remotes/"))
		return 1;

	return 0;
}

static int interpret_branch_mark(struct repository *r,
				 const char *name, int namelen,
				 int at, struct strbuf *buf,
				 int (*get_mark)(const char *, int),
				 const char *(*get_data)(struct branch *,
							 struct strbuf *),
				 const struct interpret_branch_name_options *options)
{
	int len;
	struct branch *branch;
	struct strbuf err = STRBUF_INIT;
	const char *value;

	len = get_mark(name + at, namelen - at);
	if (!len)
		return -1;

	if (memchr(name, ':', at))
		return -1;

	if (at) {
		char *name_str = xmemdupz(name, at);
		branch = branch_get(name_str);
		free(name_str);
	} else
		branch = branch_get(NULL);

	value = get_data(branch, &err);
	if (!value) {
		if (options->nonfatal_dangling_mark) {
			strbuf_release(&err);
			return -1;
		} else {
			die("%s", err.buf);
		}
	}

	if (!branch_interpret_allowed(value, options->allowed))
		return -1;

	set_shortened_ref(r, buf, value);
	return len + at;
}

int repo_interpret_branch_name(struct repository *r,
			       const char *name, int namelen,
			       struct strbuf *buf,
			       const struct interpret_branch_name_options *options)
{
	char *at;
	const char *start;
	int len;

	if (!namelen)
		namelen = strlen(name);

	if (!options->allowed || (options->allowed & INTERPRET_BRANCH_LOCAL)) {
		len = interpret_nth_prior_checkout(r, name, namelen, buf);
		if (!len) {
			return len; /* syntax Ok, not enough switches */
		} else if (len > 0) {
			if (len == namelen)
				return len; /* consumed all */
			else
				return reinterpret(r, name, namelen, len, buf,
						   options->allowed);
		}
	}

	for (start = name;
	     (at = memchr(start, '@', namelen - (start - name)));
	     start = at + 1) {

		if (!options->allowed || (options->allowed & INTERPRET_BRANCH_HEAD)) {
			len = interpret_empty_at(name, namelen, at - name, buf);
			if (len > 0)
				return reinterpret(r, name, namelen, len, buf,
						   options->allowed);
		}

		len = interpret_branch_mark(r, name, namelen, at - name, buf,
					    upstream_mark, branch_get_upstream,
					    options);
		if (len > 0)
			return len;

		len = interpret_branch_mark(r, name, namelen, at - name, buf,
					    push_mark, branch_get_push,
					    options);
		if (len > 0)
			return len;
	}

	return -1;
}

void object_context_release(struct object_context *ctx)
{
	free(ctx->path);
	strbuf_release(&ctx->symlink_path);
}

int repo_get_oid_with_flags(struct repository *r, const char *name,
			    struct object_id *oid, unsigned flags)
{
	struct object_context unused;
	int ret = get_oid_with_context(r, name, flags, oid, &unused);
	object_context_release(&unused);
	return ret;
}

int repo_get_oid(struct repository *r, const char *name, struct object_id *oid)
{
	return repo_get_oid_with_flags(r, name, oid, 0);
}

/*
 * This returns a non-zero value if the string (built using printf
 * format and the given arguments) is not a valid object.
 */
int get_oidf(struct object_id *oid, const char *fmt, ...)
{
	va_list ap;
	int ret;
	struct strbuf sb = STRBUF_INIT;

	va_start(ap, fmt);
	strbuf_vaddf(&sb, fmt, ap);
	va_end(ap);

	ret = repo_get_oid(the_repository, sb.buf, oid);
	strbuf_release(&sb);

	return ret;
}

/*
 * Many callers know that the user meant to name a commit-ish by
 * syntactical positions where the object name appears.  Calling this
 * function allows the machinery to disambiguate shorter-than-unique
 * abbreviated object names between commit-ish and others.
 *
 * Note that this does NOT error out when the named object is not a
 * commit-ish. It is merely to give a hint to the disambiguation
 * machinery.
 */
int repo_get_oid_committish(struct repository *r,
			    const char *name,
			    struct object_id *oid)
{
	struct object_context unused;
	int ret = get_oid_with_context(r, name, GET_OID_COMMITTISH,
				       oid, &unused);
	object_context_release(&unused);
	return ret;
}

int repo_get_oid_treeish(struct repository *r,
			 const char *name,
			 struct object_id *oid)
{
	struct object_context unused;
	int ret = get_oid_with_context(r, name, GET_OID_TREEISH,
				       oid, &unused);
	object_context_release(&unused);
	return ret;
}

int repo_get_oid_commit(struct repository *r,
			const char *name,
			struct object_id *oid)
{
	struct object_context unused;
	int ret = get_oid_with_context(r, name, GET_OID_COMMIT,
				       oid, &unused);
	object_context_release(&unused);
	return ret;
}

int repo_get_oid_tree(struct repository *r,
		      const char *name,
		      struct object_id *oid)
{
	struct object_context unused;
	int ret = get_oid_with_context(r, name, GET_OID_TREE,
				       oid, &unused);
	object_context_release(&unused);
	return ret;
}

int repo_get_oid_blob(struct repository *r,
		      const char *name,
		      struct object_id *oid)
{
	struct object_context unused;
	int ret = get_oid_with_context(r, name, GET_OID_BLOB,
				       oid, &unused);
	object_context_release(&unused);
	return ret;
}

/* Must be called only when object_name:filename doesn't exist. */
static void diagnose_invalid_oid_path(struct repository *r,
				      const char *prefix,
				      const char *filename,
				      const struct object_id *tree_oid,
				      const char *object_name,
				      int object_name_len)
{
	struct object_id oid;
	unsigned short mode;

	if (!prefix)
		prefix = "";

	if (file_exists(filename))
		die(_("path '%s' exists on disk, but not in '%.*s'"),
		    filename, object_name_len, object_name);
	if (is_missing_file_error(errno)) {
		char *fullname = xstrfmt("%s%s", prefix, filename);

		if (!get_tree_entry(r, tree_oid, fullname, &oid, &mode)) {
			die(_("path '%s' exists, but not '%s'\n"
			    "hint: Did you mean '%.*s:%s' aka '%.*s:./%s'?"),
			    fullname,
			    filename,
			    object_name_len, object_name,
			    fullname,
			    object_name_len, object_name,
			    filename);
		}
		die(_("path '%s' does not exist in '%.*s'"),
		    filename, object_name_len, object_name);
	}
}

/* Must be called only when :stage:filename doesn't exist. */
static void diagnose_invalid_index_path(struct repository *r,
					int stage,
					const char *prefix,
					const char *filename)
{
	struct index_state *istate = r->index;
	const struct cache_entry *ce;
	int pos;
	unsigned namelen = strlen(filename);
	struct strbuf fullname = STRBUF_INIT;

	if (!prefix)
		prefix = "";

	/* Wrong stage number? */
	pos = index_name_pos(istate, filename, namelen);
	if (pos < 0)
		pos = -pos - 1;
	if (pos < istate->cache_nr) {
		ce = istate->cache[pos];
		if (!S_ISSPARSEDIR(ce->ce_mode) &&
		    ce_namelen(ce) == namelen &&
		    !memcmp(ce->name, filename, namelen))
			die(_("path '%s' is in the index, but not at stage %d\n"
			    "hint: Did you mean ':%d:%s'?"),
			    filename, stage,
			    ce_stage(ce), filename);
	}

	/* Confusion between relative and absolute filenames? */
	strbuf_addstr(&fullname, prefix);
	strbuf_addstr(&fullname, filename);
	pos = index_name_pos(istate, fullname.buf, fullname.len);
	if (pos < 0)
		pos = -pos - 1;
	if (pos < istate->cache_nr) {
		ce = istate->cache[pos];
		if (!S_ISSPARSEDIR(ce->ce_mode) &&
		    ce_namelen(ce) == fullname.len &&
		    !memcmp(ce->name, fullname.buf, fullname.len))
			die(_("path '%s' is in the index, but not '%s'\n"
			    "hint: Did you mean ':%d:%s' aka ':%d:./%s'?"),
			    fullname.buf, filename,
			    ce_stage(ce), fullname.buf,
			    ce_stage(ce), filename);
	}

	if (repo_file_exists(r, filename))
		die(_("path '%s' exists on disk, but not in the index"), filename);
	if (is_missing_file_error(errno))
		die(_("path '%s' does not exist (neither on disk nor in the index)"),
		    filename);

	strbuf_release(&fullname);
}


static char *resolve_relative_path(struct repository *r, const char *rel)
{
	if (!starts_with(rel, "./") && !starts_with(rel, "../"))
		return NULL;

	if (r != the_repository || !is_inside_work_tree())
		die(_("relative path syntax can't be used outside working tree"));

	/* die() inside prefix_path() if resolved path is outside worktree */
	return prefix_path(startup_info->prefix,
			   startup_info->prefix ? strlen(startup_info->prefix) : 0,
			   rel);
}

static int reject_tree_in_index(struct repository *repo,
				int only_to_die,
				const struct cache_entry *ce,
				int stage,
				const char *prefix,
				const char *cp)
{
	if (!S_ISSPARSEDIR(ce->ce_mode))
		return 0;
	if (only_to_die)
		diagnose_invalid_index_path(repo, stage, prefix, cp);
	return -1;
}

static enum get_oid_result get_oid_with_context_1(struct repository *repo,
				  const char *name,
				  unsigned flags,
				  const char *prefix,
				  struct object_id *oid,
				  struct object_context *oc)
{
	int ret, bracket_depth;
	int namelen = strlen(name);
	const char *cp;
	int only_to_die = flags & GET_OID_ONLY_TO_DIE;

	memset(oc, 0, sizeof(*oc));
	oc->mode = S_IFINVALID;
	strbuf_init(&oc->symlink_path, 0);
	ret = get_oid_1(repo, name, namelen, oid, flags);
	if (!ret && flags & GET_OID_REQUIRE_PATH)
		die(_("<object>:<path> required, only <object> '%s' given"),
		    name);
	if (!ret)
		return ret;
	/*
	 * tree:path --> object name of path in tree
	 * :path -> object name of absolute path in index
	 * :./path -> object name of path relative to cwd in index
	 * :[0-3]:path -> object name of path in index at stage
	 * :/foo -> recent commit matching foo
	 */
	if (name[0] == ':') {
		int stage = 0;
		const struct cache_entry *ce;
		char *new_path = NULL;
		int pos;
		if (!only_to_die && namelen > 2 && name[1] == '/') {
			struct handle_one_ref_cb cb;
			struct commit_list *list = NULL;

			cb.repo = repo;
			cb.list = &list;
			refs_for_each_ref(get_main_ref_store(repo), handle_one_ref, &cb);
			refs_head_ref(get_main_ref_store(repo), handle_one_ref, &cb);
			ret = get_oid_oneline(repo, name + 2, oid, list);

			free_commit_list(list);
			return ret;
		}
		if (namelen < 3 ||
		    name[2] != ':' ||
		    name[1] < '0' || '3' < name[1])
			cp = name + 1;
		else {
			stage = name[1] - '0';
			cp = name + 3;
		}
		new_path = resolve_relative_path(repo, cp);
		if (!new_path) {
			namelen = namelen - (cp - name);
		} else {
			cp = new_path;
			namelen = strlen(cp);
		}

		if (flags & GET_OID_RECORD_PATH)
			oc->path = xstrdup(cp);

		if (!repo->index || !repo->index->cache)
			repo_read_index(repo);
		pos = index_name_pos(repo->index, cp, namelen);
		if (pos < 0)
			pos = -pos - 1;
		while (pos < repo->index->cache_nr) {
			ce = repo->index->cache[pos];
			if (ce_namelen(ce) != namelen ||
			    memcmp(ce->name, cp, namelen))
				break;
			if (ce_stage(ce) == stage) {
				free(new_path);
				if (reject_tree_in_index(repo, only_to_die, ce,
							 stage, prefix, cp))
					return -1;
				oidcpy(oid, &ce->oid);
				oc->mode = ce->ce_mode;
				return 0;
			}
			pos++;
		}
		if (only_to_die && name[1] && name[1] != '/')
			diagnose_invalid_index_path(repo, stage, prefix, cp);
		free(new_path);
		return -1;
	}
	for (cp = name, bracket_depth = 0; *cp; cp++) {
		if (strchr("@^", *cp) && cp[1] == '{') {
			cp++;
			bracket_depth++;
		} else if (bracket_depth && *cp == '}') {
			bracket_depth--;
		} else if (!bracket_depth && *cp == ':') {
			break;
		}
	}
	if (*cp == ':') {
		struct object_id tree_oid;
		int len = cp - name;
		unsigned sub_flags = flags;

		sub_flags &= ~GET_OID_DISAMBIGUATORS;
		sub_flags |= GET_OID_TREEISH;

		if (!get_oid_1(repo, name, len, &tree_oid, sub_flags)) {
			const char *filename = cp+1;
			char *new_filename = NULL;

			new_filename = resolve_relative_path(repo, filename);
			if (new_filename)
				filename = new_filename;
			if (flags & GET_OID_FOLLOW_SYMLINKS) {
				ret = get_tree_entry_follow_symlinks(repo, &tree_oid,
					filename, oid, &oc->symlink_path,
					&oc->mode);
			} else {
				ret = get_tree_entry(repo, &tree_oid, filename, oid,
						     &oc->mode);
				if (ret && only_to_die) {
					diagnose_invalid_oid_path(repo, prefix,
								   filename,
								   &tree_oid,
								   name, len);
				}
			}
			if (flags & GET_OID_RECORD_PATH)
				oc->path = xstrdup(filename);

			free(new_filename);
			return ret;
		} else {
			if (only_to_die)
				die(_("invalid object name '%.*s'."), len, name);
		}
	}
	return ret;
}

/*
 * Call this function when you know "name" given by the end user must
 * name an object but it doesn't; the function _may_ die with a better
 * diagnostic message than "no such object 'name'", e.g. "Path 'doc' does not
 * exist in 'HEAD'" when given "HEAD:doc", or it may return in which case
 * you have a chance to diagnose the error further.
 */
void maybe_die_on_misspelt_object_name(struct repository *r,
				       const char *name,
				       const char *prefix)
{
	struct object_context oc;
	struct object_id oid;
	get_oid_with_context_1(r, name, GET_OID_ONLY_TO_DIE | GET_OID_QUIETLY,
			       prefix, &oid, &oc);
	object_context_release(&oc);
}

enum get_oid_result get_oid_with_context(struct repository *repo,
					 const char *str,
					 unsigned flags,
					 struct object_id *oid,
					 struct object_context *oc)
{
	if (flags & GET_OID_FOLLOW_SYMLINKS && flags & GET_OID_ONLY_TO_DIE)
		BUG("incompatible flags for get_oid_with_context");
	return get_oid_with_context_1(repo, str, flags, NULL, oid, oc);
}
