How to disambiguate an ambiguous abbreviated sha1 in git

I was intrigued by Josh Stone’s analysis of sha1 abbreviation collisions.

Let’s say somebody wrote down an abbreviated commit id, 8b82547e33, at a time when it was unambiguous. But since then other objects have been created with that same prefix, so that now git tells you (twice, for some reason):

  • Database issue (orphaned migrations) when using git flow branches
  • Git error on git pull (unable to update local ref)
  • Hudson infinite loop polling for changes in Git repository?
  • Modify a previously committed change in git
  • How to remove commit remotely after another commits
  • Git merge from someone else's fork
  • $ git show 8b82547e33
    error: short SHA1 8b82547e33 is ambiguous.
    error: short SHA1 8b82547e33 is ambiguous.
    fatal: ambiguous argument '8b82547e33': unknown revision or path not in the working tree.
    Use '--' to separate paths from revisions, like this:
    'git <command> [<revision>...] -- [<file>...]'
    

    Now, as a human, I could probably tell which object I meant if git would just show me the ambiguous objects. How can I achieve something like the following?

    $ git objects-starting-with 8b82547e33
    8b82547e33e: commit: l2tp: Restore socket refcount when sendmsg succeeds
    8b82547e338: tree [2 files, 26 subtrees]
    

    (Note: the above examples are using a relatively current clone of http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git.)

  • git alias with formatting in .gitconfig
  • ssh authentication problem with git submodules in windows
  • Git - Diff between branches in old commits
  • git push error: RPC failed; result=56, HTTP code = 0
  • cloned repo, its branches and git checkout
  • How do I stop Github changing my project name?
  • 2 Solutions collect form web for “How to disambiguate an ambiguous abbreviated sha1 in git”

    You can use git rev-parse, assuming you have at least a 4-digit prefix of the full hash.

    git rev-parse --disambiguate=8b82547e33
    

    With Git 2.11+ (Q4 2016), you won’t even have to type git rev-parse --disambiguate=....

    Git will list for you the possible candidates!

    See commit 5b33cb1 (27 Sep 2016), and commit 1ffa26c, commit fad6b9e, commit 16ddcd4, commit 0c99171, commit 59e4e34, commit 0016043, commit 5d5def2, commit 8a10fea, commit 7243ffd, commit 259942f (26 Sep 2016) by Jeff King (peff).
    (Merged by Junio C Hamano — gitster — in commit 66c22ba, 06 Oct 2016)

    get_short_sha1: list ambiguous objects on error

    When the user gives us an ambiguous short sha1, we print an error and refuse to resolve it.
    In some cases, the next step is for them to feed us more characters (e.g., if they were retyping or cut-and-pasting from a full sha1). But in other cases, that might be all they have.

    For example, an old commit message may have used a 7-character hex that was
    unique at the time, but is now ambiguous.
    Git doesn’t provide any information about the ambiguous objects it found, so it’s hard for the user to find out which one they probably meant.

    This patch teaches get_short_sha1() to list the sha1s of the objects it found, along with a few bits of information that may help the user decide which one they meant.
    Here’s what it looks like on git.git:

      $ git rev-parse b2e1
      error: short SHA1 b2e1 is ambiguous
      hint: The candidates are:
      hint:   b2e1196 tag v2.8.0-rc1
      hint:   b2e11d1 tree
      hint:   b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
      hint:   b2e1759 blob
      hint:   b2e18954 blob
      hint:   b2e1895c blob
      fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
      Use '--' to separate paths from revisions, like this:
      'git <command> [<revision>...] -- [<file>...]'
    

    We show the tagname for tags, and the date and subject for commits.
    For trees and blobs, in theory we could dig in the history to find the paths at which they were present. But that’s very expensive (on the order of 30s for the kernel), and it’s not likely to be all that helpful.
    Most short references are to commits, so the useful information is typically going to be that the object in question isn’t a commit. So it’s silly to spend a lot of CPU preemptively digging up the path; the user can do it themselves if they really need to.

    And of course it’s somewhat ironic that we abbreviate the sha1s in the disambiguation hint.
    But full sha1s would cause annoying line wrapping for the commit lines, and presumably the user is going to just re-issue their command immediately with the corrected sha1.

    We also restrict the list to those that match any disambiguation hint. E.g.:

      $ git rev-parse b2e1:foo
      error: short SHA1 b2e1 is ambiguous
      hint: The candidates are:
      hint:   b2e1196 tag v2.8.0-rc1
      hint:   b2e11d1 tree
      hint:   b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
      fatal: Invalid object name 'b2e1'.
    

    does not bother reporting the blobs, because they cannot work as a treeish.

    Git Baby is a git and github fan, let's start git clone.