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


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

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

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

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

5 146

5 ответов:

на этот вопрос на самом деле ответили в Глава 7 книги Pro Git:

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

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

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

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

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


для больших РЕПО, 7 не достаточно с 2010 года, и commit dce9648 сам Линус Торвальдс (git 1.7.4.4, Oct 2010):

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

(BK = BitKeeper)

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

мы оба должны увеличить аббревиатуру по умолчанию, которая была нереально маленькой,и добавить способ для людей, чтобы установить их по умолчанию для каждого проекта в Git файл config.

core.abbrev

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

environment.c:

int minimum_abbrev = 4, default_abbrev = 7;

Примечание:прокомментировал ниже by Марко.м,core.abbrevLenght была переименована в core.abbrev в том же Git 1.7.4.4 in commit a71f09f

переименовать core.abbrevlength на core.abbrev

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


совсем недавно Линус добавил в commit e6c587c (для Git 2.11, Q4 2016):
(как уже упоминалось в Матье Мой ' s ответ)

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

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

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

посмотреть commit e6c587c (01 Oct 2016) by Линус Торвальдс (torvalds).
Смотрите commit 7b5b772,совершить 65acfea (01 Oct 2016) by Junio C Hamano (gitster).
(слитый Junio C Hamano--gitster-- на commit bb188d0, 03 окт 2016)

это новое свойство (угадывание разумного значения по умолчанию для значения аббревиатуры SHA1) имеет прямое влияние на то, как ГИТ вычислить свой собственный номер версии для освобождения.

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

для вероятностей менее 1/2 вероятность столкновения можно аппроксимировать как

p ~ = (n2)/(2М)

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

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

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

30K ~= 215

p ~ = (n2) / (2m) ~ = ((215)2)/(2*168) = 230/233 = ⅛

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

p ~ = (n2) / (2m) ~ = ((215)2)/(2*1612) = 230/249 = 2-19

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

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

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

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

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