summaryrefslogtreecommitdiff
path: root/sha1_name.c
diff options
context:
space:
mode:
Diffstat (limited to 'sha1_name.c')
-rw-r--r--sha1_name.c59
1 files changed, 50 insertions, 9 deletions
diff --git a/sha1_name.c b/sha1_name.c
index 18fac921dd..8bc20c54b1 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -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;