When editing a file managed by Git, vc-annotate shows the output of git blame. As Git usually does, revisions are identified by a short commit id.

The short commit id is abbreviated to be one character longer than in the output of every other command. This breaks workflows where I use the annotate buffer to navigate to a commit, copy the revision (which is an abbreviated commit id), and search this abbreviated commit id elsewhere (git log --oneline, Magit control buffer, git rebase -i commit list, …). I need to remove the last character from the commit id.

If I can't convince Git itself to use the same short commit length for git blame as for other commands, how can I make vc-annotate strip the last character of commit ids?

A quick look at the vc code doesn't reveal an obvious way to run a hook after a specific command for a specific version control system.

  • Of course git might need to show you a longer hash than it would normally do, in order to avoid collisions. IIRC it will display a currently-unique abbreviation. Do you know how that interacts with the behaviour you're describing? If adding one extra char for uniquification purposes does not result in two extra chars in vc-annotate, then stripping the final char could occasionally leave you with a non-unique hash.
    – phils
    Nov 16, 2020 at 0:19
  • @phils Git selects a hash length for uniqueness in the repository, but then its blame command adds one only for the sake of the boundary commit (very unusually: boundary commits) which is displayed as ^1234567 instead of 12345678 so that 1234567 is unique and not just 12345678. The chances that this would be relevant in an interactive workflow, especially in this case where I'm looking at the whole history and so a single commit is the boundary commit, are extremely remote and not worth the aggravation of the extra characters. Nov 16, 2020 at 9:34

1 Answer 1


I resolved this at the Git level by creating a custom Git command blame-1 which abbreviates commit IDs to the standard length. See https://stackoverflow.com/questions/64849093/use-the-same-commit-abbreviation-length-for-git-blame-as-other-commands/77788346#77788346

In my Emacs init file, I use the following code to use git blame-1 instead of git blame for vc-annotate.

(defvar my-git-have-blame-1 'unknown)

(defun my-after-load-vc-git ()
  (defun my-git-have-blame-1-update ()
    (setq my-git-have-blame-1
          (and (save-match-data
                  (executable-find "git-blame-1")
                  (let ((aliases (vc-git--run-command-string
                                  nil "config"
                                  "--get-regexp" "^alias\\.")))
                    (string-match "^alias\\.blame-1 " aliases))))

  (defun my-git-have-blame-1 ()
    (if (eq my-git-have-blame-1 'unknown)

  (defadvice vc-git-command
      (before vc-git-command-use-my-aliases compile activate)
    (when (and (equal "blame" (ad-get-arg 3))
      (ad-set-arg 3 "blame-1")))

(eval-after-load "vc-git" '(my-after-load-vc-git))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.