diff --git a/sha1_name.c b/sha1_name.c
index f64755fbceea617c424b9b83999eeaa91bf76af1..4e9a052333dcbb538866766f68b4fe18f615fe4d 100644 (file)
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -119,6 +119,9 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
return found;
}
+#define SHORT_NAME_NOT_FOUND (-1)
+#define SHORT_NAME_AMBIGUOUS (-2)
+
static int find_unique_short_object(int len, char *canonical,
unsigned char *res, unsigned char *sha1)
{
has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
has_packed = find_short_packed_object(len, res, packed_sha1);
if (!has_unpacked && !has_packed)
- return -1;
+ return SHORT_NAME_NOT_FOUND;
if (1 < has_unpacked || 1 < has_packed)
- return error("short SHA1 %.*s is ambiguous.", len, canonical);
+ return SHORT_NAME_AMBIGUOUS;
if (has_unpacked != has_packed) {
memcpy(sha1, (has_packed ? packed_sha1 : unpacked_sha1), 20);
return 0;
}
/* Both have unique ones -- do they match? */
if (memcmp(packed_sha1, unpacked_sha1, 20))
- return error("short SHA1 %.*s is ambiguous.", len, canonical);
+ return -2;
memcpy(sha1, packed_sha1, 20);
return 0;
}
-static int get_short_sha1(const char *name, int len, unsigned char *sha1)
+static int get_short_sha1(const char *name, int len, unsigned char *sha1,
+ int quietly)
{
- int i;
+ int i, status;
char canonical[40];
unsigned char res[20];
res[i >> 1] |= val;
}
- return find_unique_short_object(i, canonical, res, sha1);
+ status = find_unique_short_object(i, canonical, res, sha1);
+ if (!quietly && (status == SHORT_NAME_AMBIGUOUS))
+ return error("short SHA1 %.*s is ambiguous.", len, canonical);
+ return status;
+}
+
+const char *find_unique_abbrev(const unsigned char *sha1, int len)
+{
+ int status;
+ static char hex[41];
+ memcpy(hex, sha1_to_hex(sha1), 40);
+ while (len < 40) {
+ unsigned char sha1_ret[20];
+ status = get_short_sha1(hex, len, sha1_ret, 1);
+ if (!status) {
+ hex[len] = 0;
+ return hex;
+ }
+ if (status != SHORT_NAME_AMBIGUOUS)
+ return NULL;
+ len++;
+ }
+ return NULL;
}
static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
ret = get_sha1_basic(name, len, sha1);
if (!ret)
return 0;
- return get_short_sha1(name, len, sha1);
+ return get_short_sha1(name, len, sha1, 0);
}
/*