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 60d5c9f5b -- \
      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 <gitster@pobox.com>
This commit is contained in:
Junio C Hamano
2012-07-02 00:54:00 -07:00
parent f174a2583c
commit b31272f704

View File

@ -1828,6 +1828,16 @@ static int read_ancestry(const char *graft_file)
return 0; return 0;
} }
static int update_auto_abbrev(int auto_abbrev, struct origin *suspect)
{
const char *uniq = find_unique_abbrev(suspect->commit->object.sha1,
auto_abbrev);
int len = strlen(uniq);
if (auto_abbrev < len)
return len;
return auto_abbrev;
}
/* /*
* How many columns do we need to show line numbers in decimal? * How many columns do we need to show line numbers in decimal?
*/ */
@ -1850,12 +1860,16 @@ static void find_alignment(struct scoreboard *sb, int *option)
int longest_dst_lines = 0; int longest_dst_lines = 0;
unsigned largest_score = 0; unsigned largest_score = 0;
struct blame_entry *e; struct blame_entry *e;
int compute_auto_abbrev = (abbrev < 0);
int auto_abbrev = default_abbrev;
for (e = sb->ent; e; e = e->next) { for (e = sb->ent; e; e = e->next) {
struct origin *suspect = e->suspect; struct origin *suspect = e->suspect;
struct commit_info ci; struct commit_info ci;
int num; int num;
if (compute_auto_abbrev)
auto_abbrev = update_auto_abbrev(auto_abbrev, suspect);
if (strcmp(suspect->path, sb->path)) if (strcmp(suspect->path, sb->path))
*option |= OUTPUT_SHOW_NAME; *option |= OUTPUT_SHOW_NAME;
num = strlen(suspect->path); num = strlen(suspect->path);
@ -1883,6 +1897,10 @@ static void find_alignment(struct scoreboard *sb, int *option)
max_orig_digits = lineno_width(longest_src_lines); max_orig_digits = lineno_width(longest_src_lines);
max_digits = lineno_width(longest_dst_lines); max_digits = lineno_width(longest_dst_lines);
max_score_digits = lineno_width(largest_score); max_score_digits = lineno_width(largest_score);
if (compute_auto_abbrev)
/* one more abbrev length is needed for the boundary commit */
abbrev = auto_abbrev + 1;
} }
/* /*
@ -2360,8 +2378,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
parse_done: parse_done:
argc = parse_options_end(&ctx); argc = parse_options_end(&ctx);
if (abbrev == -1) if (0 < abbrev)
abbrev = default_abbrev;
/* one more abbrev length is needed for the boundary commit */ /* one more abbrev length is needed for the boundary commit */
abbrev++; abbrev++;