提交 957d7406 编写于 作者: J Junio C Hamano

rev-parse --disambiguate=<prefix>

The new option allows you to feed an ambiguous prefix and enumerate
all the objects that share it as a prefix of their object names.
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 c036c4c5
......@@ -101,6 +101,12 @@ OPTIONS
The option core.warnAmbiguousRefs is used to select the strict
abbreviation mode.
--disambiguate=<prefix>::
Show every object whose name begins with the given prefix.
The <prefix> must be at least 4 hexadecimal digits long to
avoid listing each and every object in the repository by
mistake.
--all::
Show all refs found in `refs/`.
......
......@@ -195,6 +195,12 @@ static int anti_reference(const char *refname, const unsigned char *sha1, int fl
return 0;
}
static int show_abbrev(const unsigned char *sha1, void *cb_data)
{
show_rev(NORMAL, sha1, NULL);
return 0;
}
static void show_datestring(const char *flag, const char *datestr)
{
static char buffer[100];
......@@ -589,6 +595,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
for_each_ref(show_reference, NULL);
continue;
}
if (!prefixcmp(arg, "--disambiguate=")) {
for_each_abbrev(arg + 15, show_abbrev, NULL);
continue;
}
if (!strcmp(arg, "--bisect")) {
for_each_ref_in("refs/bisect/bad", show_reference, NULL);
for_each_ref_in("refs/bisect/good", anti_reference, NULL);
......
......@@ -828,6 +828,9 @@ extern int get_sha1_blob(const char *str, unsigned char *sha1);
extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix);
extern int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc);
typedef int each_abbrev_fn(const unsigned char *sha1, void *);
extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *);
/*
* Try to read a SHA1 in hexadecimal format from the 40 characters
* starting at hex. Write the 20-byte result to sha1 in binary form.
......
......@@ -20,10 +20,15 @@ struct disambiguate_state {
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 unsigned char *current)
{
if (ds->always_call_fn) {
ds->ambiguous = ds->fn(current, ds->cb_data) ? 1 : 0;
return;
}
if (!ds->candidate_exists) {
/* this is the first candidate */
hashcpy(ds->candidate, current);
......@@ -272,17 +277,12 @@ static int disambiguate_blob_only(const unsigned char *sha1, void *cb_data_unuse
return kind == OBJ_BLOB;
}
static int get_short_sha1(const char *name, int len, unsigned char *sha1,
unsigned flags)
static int prepare_prefixes(const char *name, int len,
unsigned char *bin_pfx,
char *hex_pfx)
{
int i, status;
char hex_pfx[40];
unsigned char bin_pfx[20];
struct disambiguate_state ds;
int quietly = !!(flags & GET_SHA1_QUIETLY);
int i;
if (len < MINIMUM_ABBREV || len > 40)
return -1;
hashclr(bin_pfx);
memset(hex_pfx, 'x', 40);
for (i = 0; i < len ;i++) {
......@@ -303,6 +303,22 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
val <<= 4;
bin_pfx[i >> 1] |= val;
}
return 0;
}
static int get_short_sha1(const char *name, int len, unsigned char *sha1,
unsigned flags)
{
int status;
char hex_pfx[40];
unsigned char bin_pfx[20];
struct disambiguate_state ds;
int quietly = !!(flags & GET_SHA1_QUIETLY);
if (len < MINIMUM_ABBREV || len > 40)
return -1;
if (prepare_prefixes(name, len, bin_pfx, hex_pfx) < 0)
return -1;
prepare_alt_odb();
......@@ -327,6 +343,31 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
return status;
}
int for_each_abbrev(const char *prefix, each_abbrev_fn fn, void *cb_data)
{
char hex_pfx[40];
unsigned char bin_pfx[20];
struct disambiguate_state ds;
int len = strlen(prefix);
if (len < MINIMUM_ABBREV || len > 40)
return -1;
if (prepare_prefixes(prefix, len, bin_pfx, hex_pfx) < 0)
return -1;
prepare_alt_odb();
memset(&ds, 0, sizeof(ds));
ds.always_call_fn = 1;
ds.cb_data = cb_data;
ds.fn = fn;
find_short_object_filename(len, hex_pfx, &ds);
find_short_packed_object(len, bin_pfx, &ds);
return ds.ambiguous;
}
const char *find_unique_abbrev(const unsigned char *sha1, int len)
{
int status, exists;
......
......@@ -252,4 +252,13 @@ test_expect_success 'ambiguous commit-ish' '
test_must_fail git log 000000000...
'
test_expect_success 'rev-parse --disambiguate' '
# The test creates 16 objects that share the prefix and two
# commits created by commit-tree in earlier tests do not share
# the prefix.
git rev-parse --disambiguate=000000000 >actual &&
test "$(wc -l <actual)" = 16 &&
test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000
'
test_done
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册