Skip to content

Commit 4f03666

Browse files
peffgitster
authored andcommitted
diff: handle sha1 abbreviations outside of repository
When generating diffs outside a repository (e.g., with "diff --no-index"), we may write abbreviated sha1s as part of "--raw" output or the "index" lines of "--patch" output. Since we have no object database, we never find any collisions, and these sha1s get whatever static abbreviation length is configured (typically 7). However, we do blindly look in ".git/objects" to see if any objects exist, even though we know we are not in a repository. This is usually harmless because such a directory is unlikely to exist, but could be wrong in rare circumstances. Let's instead notice when we are not in a repository and behave as if the object database is empty (i.e., just use the default abbrev length). It would perhaps make sense to be conservative and show full sha1s in that case, but showing the default abbreviation is what we've always done (and is certainly less ugly). Note that this does mean that: cd /not/a/repo GIT_OBJECT_DIRECTORY=/some/real/objdir git diff --no-index ... used to look for collisions in /some/real/objdir but now does not. This could be considered either a bugfix (we do not look at objects if we have no repository) or a regression, but it seems unlikely that anybody would care much either way. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d6cece5 commit 4f03666

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

diff.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3096,6 +3096,19 @@ static int similarity_index(struct diff_filepair *p)
30963096
return p->score * 100 / MAX_SCORE;
30973097
}
30983098

3099+
static const char *diff_abbrev_oid(const struct object_id *oid, int abbrev)
3100+
{
3101+
if (startup_info->have_repository)
3102+
return find_unique_abbrev(oid->hash, abbrev);
3103+
else {
3104+
char *hex = oid_to_hex(oid);
3105+
if (abbrev < 0 || abbrev > GIT_SHA1_HEXSZ)
3106+
die("BUG: oid abbreviation out of range: %d", abbrev);
3107+
hex[abbrev] = '\0';
3108+
return hex;
3109+
}
3110+
}
3111+
30993112
static void fill_metainfo(struct strbuf *msg,
31003113
const char *name,
31013114
const char *other,
@@ -3154,9 +3167,9 @@ static void fill_metainfo(struct strbuf *msg,
31543167
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
31553168
abbrev = 40;
31563169
}
3157-
strbuf_addf(msg, "%s%sindex %s..", line_prefix, set,
3158-
find_unique_abbrev(one->oid.hash, abbrev));
3159-
strbuf_add_unique_abbrev(msg, two->oid.hash, abbrev);
3170+
strbuf_addf(msg, "%s%sindex %s..%s", line_prefix, set,
3171+
diff_abbrev_oid(&one->oid, abbrev),
3172+
diff_abbrev_oid(&two->oid, abbrev));
31603173
if (one->mode == two->mode)
31613174
strbuf_addf(msg, " %06o", one->mode);
31623175
strbuf_addf(msg, "%s\n", reset);
@@ -4165,7 +4178,7 @@ const char *diff_aligned_abbrev(const struct object_id *oid, int len)
41654178
if (len == GIT_SHA1_HEXSZ)
41664179
return oid_to_hex(oid);
41674180

4168-
abbrev = find_unique_abbrev(oid->hash, len);
4181+
abbrev = diff_abbrev_oid(oid, len);
41694182
abblen = strlen(abbrev);
41704183

41714184
/*

0 commit comments

Comments
 (0)