Как Git создает уникальные хеши коммитов, в основном первые несколько символов?
Мне трудно понять, как Git создает уникальные хэши, которые не могут быть одинаковыми даже в первых 4 символах. Я могу вызывать коммиты в Git Bash, используя только первые четыре символа. В алгоритме конкретно определено, что первые символы являются "ультра"-уникальными и никогда не будут конфликтовать с другими подобными хэшами, или алгоритм генерирует каждую часть хеша одинаково?
2 ответа
Git использует следующую информацию для генерации sha-1:
- Исходное дерево коммита (которое раскрывается для всех поддеревьев и BLOB-объектов)
- Родительский коммит sha1
- Информация об авторе
- Информация о коммиттере (верно, это разные!)
- Сообщение коммита
(о полном объяснении; смотрите здесь).
Git НЕ гарантирует, что первые 4 символа будут уникальными. В главе 7 Pro Git Book написано:
Git может найти короткую уникальную аббревиатуру для ваших значений SHA-1. Если вы передадите --abbrev-commit в команду git log, выходные данные будут использовать более короткие значения, но будут сохранять их уникальными; по умолчанию используется семь символов, но при необходимости их удлиняют, чтобы SHA-1 оставался однозначным:
Так что Git просто делает аббревиатуру столько, сколько нужно, чтобы оставаться уникальным. Они даже отмечают, что:
Обычно от восьми до десяти символов более чем достаточно, чтобы быть уникальными в рамках проекта.
Например, ядро Linux, которое представляет собой довольно большой проект с более чем 450 тыс. Коммитов и 3,6 млн. Объектов, не имеет двух объектов, чьи SHA-1 перекрываются больше, чем первые 11 символов.
Так что на самом деле они просто зависят от невероятной вероятности иметь точно такой же (X первые символы a) ша.
Апрель 2017: Остерегайтесь того, что после всего эпизода shattered.io (где Google столкнулся с SHA1), 20-байтовый формат не будет существовать вечно.
Первым шагом для этого является замена unsigned char sha1[20]
который является жестким кодом во всей кодовой базе Git универсальным объектом, определение которого может измениться в будущем (SHA2?, Blake2,...)
Смотрите коммит e86ab2c (21 февраля 2017 г.) от brian m. Карлсон ( bk2204
)
Преобразовать оставшиеся использования
unsigned char [20]
вstruct object_id
,
Это пример текущих усилий, начатых с фиксации 5f7817c (13 марта 2015 г.) Брайаном М. Карлсон ( bk2204
), для v2.5.0-rc0, в cache.h
:
/* The length in bytes and in hex digits of an object name (SHA-1 value). */
#define GIT_SHA1_RAWSZ 20
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
struct object_id {
unsigned char hash[GIT_SHA1_RAWSZ];
};
И не забывайте, что даже с SHA1 4 первых символа уже недостаточно для гарантии уникальности, как я объясняю в " Сколько git-ша обычно считается необходимым для уникальной идентификации изменений в заданной кодовой базе? ".
Обновление в декабре 2017 года с Git 2.16 (Q1 2018): эта работа по поддержке альтернативного SHA уже ведется: см. " Почему Git не использует более современный SHA? ".
Вы сможете использовать другой хеш: SHA1 больше не единственный для Git.