Does Git warn me if a shorthand commit ID can refer to 2 different commits?

If cee157 can refer to 2 different commit IDs, such as

cee157eb799af829a9a0c42c0915f55cd29818d4 and cee1577fecf6fc5369a80bd6e926ac5f864a754b

  • error: The requested URL returned error: 403 Forbidden while accessing
  • p4merge fails when doing a directory diff?
  • Where is the Git commit info set in Xcode 4?
  • Export a stash to another computer
  • Add symlinks to git repository
  • using araxis merge for folder comparison on git branches (OSX)
  • will Git warn me if I type in git log cee157? (or Git 1.8.5.2 (Apple Git-48) allows me to type in git log cee1).

    I think it should, although I can’t find any authoritative source that says it would.

  • Why does git store objects in directories with the first two characters of the hash?
  • How to undo “git commit --amend” done instead of “git commit”
  • Jenkins unable to fetch repo - code 255 permission denied
  • Removing all files from a just initialized git repo staging area
  • Send a pull request on GitHub for only latest commit
  • How to manage a hierarchy of committers (like Linux kernel dev)
  • 2 Solutions collect form web for “Does Git warn me if a shorthand commit ID can refer to 2 different commits?”

    It should give you something like this:

    $ git log cee157
    error: short SHA1 cee157 is ambiguous.
    error: short SHA1 cee157 is ambiguous.
    fatal: ambiguous argument 'cee157': unknown revision or path not in the working tree.
    Use '--' to separate paths from revisions, like this:
    'git <command> [<revision>...] -- [<file>...]'
    

    I just tested this on a real Git repository, by finding commits with duplicate prefixes like this:

    git rev-list master | cut -c-4 | sort | uniq -c | sort -nr | head
    

    This takes the list of revisions in master, cuts out the first 4 characters and throws away the rest, count the duplicates and sort numerically. In a my relatively small repository of ~1500 commits I found quite a few revisions with a common 4-digit prefix. I chose a 4-digit prefix because that seems to be the shortest legal length supported by Git. (Doesn’t work with 3 digits or less, even if not ambiguous.)

    Btw this was not a typo, I don’t know why the error message about ambiguous SHA1 appears twice, regardless of the number of duplicate SHA1 (tried with 2 and 3):

    error: short SHA1 cee157 is ambiguous.
    error: short SHA1 cee157 is ambiguous.
    

    (Both on stderr. Actually the entire output is on stderr, nothing on stdout.)

    Tested in Windows:

    $ git --version
    git version 1.8.1.msysgit.1
    

    I think it’s safe to say that if your version is >= 1.8.1, Git will warn you of duplicates. (It will refuse to operate with duplicates.) I would guess that much older versions worked this way too.

    UPDATE

    When testing this, you need a minimum of 4-digit SHA1, because of int minimum_abbrev = 4 in environment.c. (Thanks @devnull for pointing that out!)

    The original poster states:

    I think it should, although I can’t find any authoritative source that
    says it would.

    The authoritative source can be found in the source code, get_short_sha1().

    Quoting this:

    if (!quietly && (status == SHORT_NAME_AMBIGUOUS))
        return error("short SHA1 %.*s is ambiguous.", len, hex_pfx);
    

    and this:

    if (!ds->candidate_checked)
        /*
         * If this is the only candidate, there is no point
         * calling the disambiguation hint callback.
         *
         * On the other hand, if the current candidate
         * replaced an earlier candidate that did _not_ pass
         * the disambiguation hint callback, then we do have
         * more than one objects that match the short name
         * given, so we should make sure this one matches;
         * otherwise, if we discovered this one and the one
         * that we previously discarded in the reverse order,
         * we would end up showing different results in the
         * same repository!
         */
        ds->candidate_ok = (!ds->disambiguate_fn_used ||
                            ds->fn(ds->candidate, ds->cb_data));
    
    if (!ds->candidate_ok)
        return SHORT_NAME_AMBIGUOUS;
    

    Moreover, tests also exist to ensure that the feature works as expected.

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