Какая часть git sha * обычно * считается необходимой для однозначной идентификации изменения в данной кодовой базе?

Если вы собираетесь построить, скажем, структуру каталогов, где каталог указан для фиксации в репозитории Git, и вы хотите, чтобы он был достаточно коротким, чтобы ваши глаза не кровоточили, но достаточно долго, чтобы вероятность его столкновения будет незначительной, сколько вообще требуется подстроки SHA?

Скажем, я хочу однозначно идентифицировать это изменение: https://github.com/wycats/handlebars.js/commit/e62999f9ece7d9218b9768a908f8df9c11d7e920

Я могу использовать всего лишь первые четыре символа: https://github.com/wycats/handlebars.js/commit/e629

Но я чувствую, что это было бы рискованно. Но если вы используете кодовую базу, которая через пару лет может иметь-скажем-30k, каковы шансы столкновения, если я использую 8 символов? 12? Есть ли число, которое обычно считается приемлемым для такого рода вещей?

Ответ 1

На этот вопрос действительно отвечает глава 7 книги Pro Git:

Как правило, от восьми до десяти символов более чем достаточно, чтобы быть уникальным в рамках проекта. Один из крупнейших проектов Git, ядро ​​Linux, начинает нуждаться 12 символов из возможных 40, чтобы остаться уникальный.

7 цифр - это значение Git по умолчанию для короткой SHA, поэтому для большинства проектов это отлично. Как уже упоминалось, группа "Ядро" увеличила их количество, потому что у них несколько сотен тысяч коммитов. Таким образом, для ваших транзакций ~ 30 000, 8 или 10 цифр должны быть отлично.

Ответ 2

Примечание: вы можете запросить git rev-parse --short для кратчайшего и уникального SHA1.
См. "git получить короткий хеш из обычного хэша"

git rev-parse --short=4 921103db8259eb9de72f42db8b939895f5651489
92110

Как вы можете видеть в моем примере, SHA1 имеет длину 5, даже если я задал длину 4.


Для больших репозиториев 7 недостаточно с 2010 года, а совершить dce9648 самим Линусом Торвальдсом (git 1.7.4.4, октябрь 2010):

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

(BK = BitKeeper)

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

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

core.abbrev

Установить имена объектов длины сокращены.
Если не указано, многие команды сокращают до 7 hexdigits, что может быть недостаточно для сокращенных имен объектов, чтобы оставаться уникальными в течение достаточно длительного времени.

environment.c:

int minimum_abbrev = 4, default_abbrev = 7;

Примечание. Поскольку комментарий ниже marco.m, core.abbrevLenght был переименован в core.abbrev в том же git 1.7.4.4 в совершить a71f09f

Переименуйте core.abbrevlength назад на core.abbrev

Это соответствует опции --abbrev=$n командной строки.


Совсем недавно Linus добавил в совершить e6c587c (для git 2.11, Q4 2016):
(как упоминалось в Matthieu Moy ответить)

В довольно ранние дни мы как-то решили сокращать имена объектов до 7-hexdigits, но по мере роста проектов становится все более вероятным появление таких коротких имен объектов, сделанных в предыдущие дни, и записанных в сообщениях журнала no более длинный уникальный.

В настоящее время для проекта ядра Linux требуется от 11 до 12 hexdigits, а для git требуется 10 hexdigits для уникальной идентификации объектов, которые у них есть, в то время как многие более мелкие проекты все равно могут быть в порядке с исходным значением 7-hexdigit по умолчанию. Один размер не подходит для всех проектов.

Ввести механизм, в котором мы оцениваем количество объектов в репозитории при первом запросе, чтобы сокращать имя объекта с параметром по умолчанию и вызывать стандартное значение по умолчанию для репозитория. Исходя из того, что мы увидели бы столкновение в репозитории с объектами 2^(2N) при использовании имен объектов, сокращенных до первых N бит, используйте достаточное количество hexdigits для покрытия количества объектов в репозитории.
Каждый hexdigit (4-бит), который мы добавляем к сокращенному имени, позволяет нам иметь в 4 раза (2 бита) столько объектов в репозитории.

См. commit e6c587c (01 октября 2016 г.) Линус Торвальдс (torvalds).
См. commit 7b5b772, commit 65acfea (01 октября 2016 г.) Юнио С Хамано (gitster).
(слияние Юнио С Хамано - gitster - в commit bb188d0, 03 Oct 2016)

Это новое свойство (угадывание разумного значения по умолчанию для значения SHA1 abbrev) напрямую влияет на то, как git вычислить свой номер версии для выпуска.

Ответ 3

Это называется проблемой дня рождения.

Для вероятностей, меньших 1/2, вероятность столкновения может быть аппроксимирована как

p ~ = (n 2)/(2m)

Где n - количество элементов, а m - количество возможностей для каждого элемента.

Число возможностей для шестнадцатеричной строки равно 16 c где c - количество символов.

Итак, для 8 символов и 30K совершает

30K ~ = 2 15

p ~ = (n 2)/(2m) ~ = ((2 15) 2)/(2 * 16 8) = 2 30/2 33= ⅛

Увеличение до 12 символов

p ~ = (n 2)/(2m) ~ = ((2 15) 2)/(2 * 16 12) = 2 30/2 49= 2 -19

Ответ 4

На этот вопрос был дан ответ, но для тех, кто ищет математику позади - это называется проблемой дня рождения (Wikipedia).

Речь идет о вероятности того, что у 2 (или более) людей из группы N людей будет день рождения в тот же день в году. Что аналогично вероятному 2 (или более) git, фиксируется из хранилища, имеющего N суммированных сумм, имеющих одинаковый хэш-префикс длины X.

Посмотрите на таблицу вероятностей. Например, для хэш-шестнадцатеричной строки длиной 8 вероятность столкновения достигает 1%, когда репозиторий имеет около 9300 элементов (git совершает транзакции). Вероятность составляет 110 000, вероятность - 75%. Но если у вас есть хэш-шестнадцатеричная строка длиной 12, вероятность столкновения в 100 000 фиксаций ниже 0,1%.

Ответ 5

Git версия 2.11 (или, возможно, 2.12?) будет содержать функцию, которая адаптирует количество символов, используемых в коротких идентификаторах (например, git log --oneline) к размеру проекта. Когда вы используете такую ​​версию Git, ответ на ваш вопрос может быть "выбрать любую длину Git дает вам git log --oneline, это достаточно безопасно".

Подробнее см. Изменение значения по умолчанию для "core.abbrev" ? обсуждение в Git Rev News edition 20 и совершить bb188d00f7.