diff options
authorJunio C Hamano <>2008-03-02 07:35:32 (GMT)
committerJunio C Hamano <>2008-03-02 07:52:13 (GMT)
commitb66fde9a287f64ed81d4d4a1639997ad5eedb432 (patch)
parent48411d2233aec65b612ac2b1f50540ec60f0f568 (diff)
find_unique_abbrev(): redefine semantics
The function returned NULL when no object that matches the name was found, but that made the callers more complicated, as nobody used that NULL return as an indication that no object with such a name exists. They (at least the careful ones) instead took the full 40-hexdigit and used in such a case, and the careless ones segfaulted. With this "git rev-parse --short 5555555555555555555555555555555555555555" would stop segfaulting. This is based on Jeff King's rewrite to my RFC patch, but "missing" logic swapped to "exists". The final logic reads: For existing objects, make sure the abbreviated string uniquely identifies it. Otherwise, make sure the abbreviated string is long enough so that it would not name any existing object. Signed-off-by: Junio C Hamano <>
1 files changed, 6 insertions, 7 deletions
diff --git a/sha1_name.c b/sha1_name.c
index 9d088cc..8358ba2 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -192,26 +192,25 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
const char *find_unique_abbrev(const unsigned char *sha1, int len)
- int status, is_null;
+ int status, exists;
static char hex[41];
- is_null = is_null_sha1(sha1);
+ exists = has_sha1_file(sha1);
memcpy(hex, sha1_to_hex(sha1), 40);
if (len == 40 || !len)
return hex;
while (len < 40) {
unsigned char sha1_ret[20];
status = get_short_sha1(hex, len, sha1_ret, 1);
- if (!status ||
- (is_null && status != SHORT_NAME_AMBIGUOUS)) {
+ if (exists
+ ? !status
+ : status == SHORT_NAME_NOT_FOUND) {
hex[len] = 0;
return hex;
- if (status != SHORT_NAME_AMBIGUOUS)
- return NULL;
- return NULL;
+ return hex;
static int ambiguous_path(const char *path, int len)