Как Git(Hub) обрабатывает возможные коллизии из-за коротких SHA?

И Git, и GitHub отображают короткие версии SHA — только первые 7 символов вместо всех 40 — и Git, и GitHub поддерживают использование этих коротких SHA в качестве аргументов.

E.g. git show 962a9e8

Например. https://github.com/joyent/node/commit/962a9e8

Учитывая, что пространство возможностей теперь на несколько порядков меньше, «всего» 268 миллионов, как Git и GitHub защищает от столкновений здесь? И как они с ними справляются?


person Aseem Kishore    schedule 19.08.2011    source источник
comment
Это не будет проблемой на уровне GitHub, потому что sha1 уникальны для каждого отдельного проекта.   -  person Tone    schedule 20.08.2011
comment
Два 7-символьных коротких sha1 по-прежнему вполне могут столкнуться в рамках одного проекта.   -  person Keith Thompson    schedule 20.08.2011
comment
Кто-нибудь знает, можно ли захватить коммиты через API github с коротким SHA... Например, github.com/alexnaspo/var_dumpling-chrome/commit/9e9726ac возвращает нужный мне коммит, но api.github.com/repos/alexnaspo/var_dumpling-chrome/git/commits/ не   -  person Alex Naspo    schedule 27.11.2012


Ответы (3)


Эти короткие формы предназначены только для упрощения визуального распознавания и облегчения вашей жизни легче. Git на самом деле ничего не усекает, внутри все будет обрабатываться с полным значением. Однако вы можете использовать частичный SHA-1 по своему усмотрению:

Git достаточно умен, чтобы понять, какую фиксацию вы хотели ввести, если вы укажете первые несколько символов, если ваш частичный SHA-1 имеет длину не менее четырех символов и однозначен, то есть только один объект в текущем репозитории начинается с что частичный SHA-1.

person emboss    schedule 20.08.2011
comment
Спасибо! Эта ссылка уточняет: Git может вычислить короткую уникальную аббревиатуру для ваших значений SHA-1. Если вы передадите --abbrev-commit команде git log, выходные данные будут использовать более короткие значения, но сохранят их уникальность; по умолчанию он использует семь символов, но при необходимости делает их длиннее, чтобы сохранить однозначность SHA-1. - person Aseem Kishore; 23.08.2011
comment
Еще одна полезная цитата: обычно от восьми до десяти символов более чем достаточно, чтобы быть уникальным в рамках проекта. Один из крупнейших проектов Git, ядро ​​Linux, начинает нуждаться в 12 символах из 40 возможных, чтобы оставаться уникальным. - person Aseem Kishore; 23.08.2011
comment
Ваша ссылка битая... :( - person Mrchief; 25.09.2014

У меня есть репозиторий с фиксацией с идентификатором 000182eacf99cde27d5916aa415921924b82972c.

git show 00018

показывает ревизию, но

git show 0001

отпечатки

error: short SHA1 0001 is ambiguous.
error: short SHA1 0001 is ambiguous.
fatal: ambiguous argument '0001': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

(Если вам интересно, это клон репозитория git для самого git; этот коммит сделал Линус Торвальдс в 2005 году.)

person Keith Thompson    schedule 19.08.2011
comment
Если вам нужно знать, какие объекты соответствуют вашему неоднозначному идентификатору (в данном случае 0001), вы можете сделать git rev-list --all --objects | grep ^0001. После того, как у вас есть список возможных полных SHA1, вы можете выполнить git show для каждого из них. - person Mikko Rantalainen; 22.01.2013
comment
Этот ответ показывает, как устранить неоднозначность, используя только команду git. - person Jeremy; 06.05.2016

Два примечания здесь:

  • Если вы введете y в любом месте страницы GitHub, отображающей коммит, вы увидите полные 40 байт указанного коммита.
    Это иллюстрирует emboss: GitHub ничего не обрезает.

  • И 7 шестнадцатеричных цифр (28 бит) в любом случае недостаточно с 2010 года.
    См. от самого Линуса Торвальдса (октябрь 2010 г., git 1.7.4.4):

Значение по умолчанию, равное 7, появилось довольно рано в разработке git, когда семь шестнадцатеричных цифр было много (охватывает около 250+ миллионов хеш-значений). Тогда я думал, что 65 тысяч ревизий — это много (это то, что мы собирались сделать в BK), и каждая ревизия, как правило, содержит около 5-10 новых объектов, так что миллион объектов — это большое число.

(БК = BitKeeper)

В наши дни ядро ​​даже не является самым большим проектом git, и даже ядро ​​имеет около 220 тысяч ревизий (намного больше, чем когда-либо было дерево BK), и мы приближаемся к двум миллионам объектов. В этот момент семь шестнадцатеричных цифр по-прежнему уникальны для многих из них, но когда мы говорим о разнице всего в два порядка между количеством объектов и размером хэша, будут коллизии в усеченные хэш-значения. Это уже даже близко не нереально — это происходит постоянно.

Мы должны как увеличить аббревиатуру по умолчанию, которая была нереально маленькой, так и и добавить возможность для людей устанавливать свои собственные значения по умолчанию для каждого проекта в файле конфигурации git.

person VonC    schedule 09.01.2014
comment
Мне любопытно, какой является самым большим проектом git? Или, по крайней мере, каковы некоторые из лучших примеров абсолютно огромных репозиториев git? - person GMA; 18.03.2015
comment
@GeorgeMillo Как упоминалось в blogs.atlassian.com/2014/05/ handle-big-repositories-git, у вас есть 2 вида огромных репозиториев (огромная история или огромные двоичные файлы). Примером огромного репозитория git был репозиторий Facebook: news.ycombinator.com/item?id=7648237 (с тех пор они перешли на собственную версию Mercurial) - person VonC; 18.03.2015
comment
Вы имеете в виду 7 шестнадцатеричных цифр (28 бит), а не 7 бит. - person Thomas Jacob; 25.04.2018
comment
@ThomasJacob Спасибо. Я отредактировал ответ соответственно. - person VonC; 25.04.2018
comment
@ThomasJacob Примечание: SHA1 не всегда будет алгоритмом хеширования по умолчанию, используемым в Git. Это развивается: stackoverflow.com/a/47838703/6309 - person VonC; 25.04.2018