Skip to content

Commit b31272f

Browse files
committed
blame: compute abbreviation width that ensures uniqueness
Julia Lawall noticed that in linux-next repository the commit object 60d5c9f5 (shown with the default abbreviation width baked into "git blame") in output from $ git blame -L 3675,3675 60d5c9f -- \ drivers/staging/brcm80211/brcmfmac/wl_iw.c is no longer unique in the repository, which results in "short SHA1 60d5c9f5 is ambiguous". Compute the minimum abbreviation width that ensures uniqueness when the user did not specify the --abbrev option to avoid this. Signed-off-by: Junio C Hamano <[email protected]>
1 parent f174a25 commit b31272f

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

builtin/blame.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,6 +1828,16 @@ static int read_ancestry(const char *graft_file)
18281828
return 0;
18291829
}
18301830

1831+
static int update_auto_abbrev(int auto_abbrev, struct origin *suspect)
1832+
{
1833+
const char *uniq = find_unique_abbrev(suspect->commit->object.sha1,
1834+
auto_abbrev);
1835+
int len = strlen(uniq);
1836+
if (auto_abbrev < len)
1837+
return len;
1838+
return auto_abbrev;
1839+
}
1840+
18311841
/*
18321842
* How many columns do we need to show line numbers in decimal?
18331843
*/
@@ -1850,12 +1860,16 @@ static void find_alignment(struct scoreboard *sb, int *option)
18501860
int longest_dst_lines = 0;
18511861
unsigned largest_score = 0;
18521862
struct blame_entry *e;
1863+
int compute_auto_abbrev = (abbrev < 0);
1864+
int auto_abbrev = default_abbrev;
18531865

18541866
for (e = sb->ent; e; e = e->next) {
18551867
struct origin *suspect = e->suspect;
18561868
struct commit_info ci;
18571869
int num;
18581870

1871+
if (compute_auto_abbrev)
1872+
auto_abbrev = update_auto_abbrev(auto_abbrev, suspect);
18591873
if (strcmp(suspect->path, sb->path))
18601874
*option |= OUTPUT_SHOW_NAME;
18611875
num = strlen(suspect->path);
@@ -1883,6 +1897,10 @@ static void find_alignment(struct scoreboard *sb, int *option)
18831897
max_orig_digits = lineno_width(longest_src_lines);
18841898
max_digits = lineno_width(longest_dst_lines);
18851899
max_score_digits = lineno_width(largest_score);
1900+
1901+
if (compute_auto_abbrev)
1902+
/* one more abbrev length is needed for the boundary commit */
1903+
abbrev = auto_abbrev + 1;
18861904
}
18871905

18881906
/*
@@ -2360,10 +2378,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
23602378
parse_done:
23612379
argc = parse_options_end(&ctx);
23622380

2363-
if (abbrev == -1)
2364-
abbrev = default_abbrev;
2365-
/* one more abbrev length is needed for the boundary commit */
2366-
abbrev++;
2381+
if (0 < abbrev)
2382+
/* one more abbrev length is needed for the boundary commit */
2383+
abbrev++;
23672384

23682385
if (revs_file && read_ancestry(revs_file))
23692386
die_errno("reading graft file '%s' failed", revs_file);

0 commit comments

Comments
 (0)