4

The git blame command shows commit hashes abbreviated to a length that is one character longer than other commands. For example:

$ git log --oneline       
9fb6f706 (HEAD -> master) second commit
0af747a8 first commit
$ git blame foo   
9fb6f7064 (gilles 2020-11-15 12:28:09 +0100 1) revised
^0af747a8 (gilles 2020-11-15 12:27:41 +0100 2) world

I frequently copy-paste an abbreviated hash from the blame output and search for it in logs or in the set of commits in an interactive rebase. But because the abbreviation is one character longer in the git blame output, I have to remember to delete the last character, otherwise the search can't find anything.

For scripting I'd use unabbreviated hashes and porcelain formats. But for interactive use, I want to use abbreviated hashes.

Setting the core.abbrev option doesn't help: git blame adds one to that. Setting core.abbrev and calling blame --abbrev with a value that's one less works, but is not a good solution because I lose the benefit of git's heuristics to determine a good length for short commit ids, and I have to pass this option explicitly or use a different command name as an alias.

How can I make a plain git blame use the same length for abbreviated commit ids as other git commands?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • That's interesting … Maybe a bug? I can confirm this behavior with latest Git built from source. Can you take this to the Git mailing list? – knittl Nov 15 '20 at 21:37
  • 1
    @knittl It's by design: [“one more abbrev length is needed for the boundary commit”](https://github.com/git/git/blob/v2.29.2/builtin/blame.c#L660). But that's only for a corner case which is mostly useless (the boundary commit is identifiable by other means anyway) and it's annoying, so I'm looking for a workaround. – Gilles 'SO- stop being evil' Nov 15 '20 at 21:59
  • 2
    Given the source code, it looks like you can't really get around it (well, I suppose you could use an alias to invoke `git blame` with an explicitly shortened abbreviation count). You might try getting in the habit of just always deleting the last character from all searches. :-) – torek Nov 16 '20 at 01:29
  • very annoying, looking for the hash commit of blame and after waste many time realize that blame hash have one more character – Sérgio Mar 03 '23 at 14:31

1 Answers1

1

Thanks for digging through the source code. I'm afraid your only solution – rather workaround is to define a custom alias.

git config --global alias.blame2 '!git -c core.abbrev=6 blame'
knittl
  • 246,190
  • 53
  • 318
  • 364
  • Even though I still don't know why blame (or "boundary commits" in blame) would require a different abbreviation length. As long as the abbrev has enough digits, it is already unique. I'd still suggest taking this to the Git mailing list – knittl Nov 16 '20 at 18:05
  • It's explained in the [commit message that inroduced the `+ 1`](https://github.com/git/git/commit/b31272f704d03258a90b0e83e0f5c8df5c038ae6): the boundary commit is shown as `^1234567` instead of `12345678`, and git calculates the length in order to ensure that `12345678` is guaranteed to be unique, but `1234567` isn't guaranteed to be unique. I'm not convinced that this corner case is worth the trouble, but I have to live with it. – Gilles 'SO- stop being evil' Nov 16 '20 at 19:10
  • 1
    @Gilles'SO-stopbeingevil': yes, but the uniqueness is not affected by the commit being a boundary commit or not. Either 7 characters are sufficient to guarantee uniqueness, or 8 are. That applies regardless of the "boundariness" of the commit. If 7 characters do not uniquely identify a single commit – i.e. the hash prefix is ambiguous – then even for `git log`, more than 7 characters have to be displayed. – knittl Nov 17 '20 at 14:06