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: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
c036c4c5e4
commit
957d74062c
@ -101,6 +101,12 @@ OPTIONS
|
|||||||
The option core.warnAmbiguousRefs is used to select the strict
|
The option core.warnAmbiguousRefs is used to select the strict
|
||||||
abbreviation mode.
|
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::
|
--all::
|
||||||
Show all refs found in `refs/`.
|
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;
|
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 void show_datestring(const char *flag, const char *datestr)
|
||||||
{
|
{
|
||||||
static char buffer[100];
|
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);
|
for_each_ref(show_reference, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!prefixcmp(arg, "--disambiguate=")) {
|
||||||
|
for_each_abbrev(arg + 15, show_abbrev, NULL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp(arg, "--bisect")) {
|
if (!strcmp(arg, "--bisect")) {
|
||||||
for_each_ref_in("refs/bisect/bad", show_reference, NULL);
|
for_each_ref_in("refs/bisect/bad", show_reference, NULL);
|
||||||
for_each_ref_in("refs/bisect/good", anti_reference, NULL);
|
for_each_ref_in("refs/bisect/good", anti_reference, NULL);
|
||||||
|
3
cache.h
3
cache.h
@ -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 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);
|
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
|
* 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.
|
* starting at hex. Write the 20-byte result to sha1 in binary form.
|
||||||
|
59
sha1_name.c
59
sha1_name.c
@ -20,10 +20,15 @@ struct disambiguate_state {
|
|||||||
unsigned candidate_ok:1;
|
unsigned candidate_ok:1;
|
||||||
unsigned disambiguate_fn_used:1;
|
unsigned disambiguate_fn_used:1;
|
||||||
unsigned ambiguous:1;
|
unsigned ambiguous:1;
|
||||||
|
unsigned always_call_fn:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void update_candidates(struct disambiguate_state *ds, const unsigned char *current)
|
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) {
|
if (!ds->candidate_exists) {
|
||||||
/* this is the first candidate */
|
/* this is the first candidate */
|
||||||
hashcpy(ds->candidate, current);
|
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;
|
return kind == OBJ_BLOB;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_short_sha1(const char *name, int len, unsigned char *sha1,
|
static int prepare_prefixes(const char *name, int len,
|
||||||
unsigned flags)
|
unsigned char *bin_pfx,
|
||||||
|
char *hex_pfx)
|
||||||
{
|
{
|
||||||
int i, status;
|
int i;
|
||||||
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;
|
|
||||||
hashclr(bin_pfx);
|
hashclr(bin_pfx);
|
||||||
memset(hex_pfx, 'x', 40);
|
memset(hex_pfx, 'x', 40);
|
||||||
for (i = 0; i < len ;i++) {
|
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;
|
val <<= 4;
|
||||||
bin_pfx[i >> 1] |= val;
|
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();
|
prepare_alt_odb();
|
||||||
|
|
||||||
@ -327,6 +343,31 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
|
|||||||
return status;
|
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)
|
const char *find_unique_abbrev(const unsigned char *sha1, int len)
|
||||||
{
|
{
|
||||||
int status, exists;
|
int status, exists;
|
||||||
|
@ -252,4 +252,13 @@ test_expect_success 'ambiguous commit-ish' '
|
|||||||
test_must_fail git log 000000000...
|
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
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user