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

Git

Git Problem Overview


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

cee157eb799af829a9a0c42c0915f55cd29818d4 and cee1577fecf6fc5369a80bd6e926ac5f864a754b

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.

Git Solutions


Solution 1 - Git

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!)

Solution 2 - Git

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnonopolarityView Question on Stackoverflow
Solution 1 - GitjanosView Answer on Stackoverflow
Solution 2 - GitdevnullView Answer on Stackoverflow