Как Git создает уникальные хэши фиксации, в основном первые несколько символов?
Мне трудно понять, как Git создает полностью уникальные хэши, которые не могут быть одинаковыми даже в первых 4 символах. Я могу вызывать коммиты в Git Bash, используя только первые четыре символа. В алгоритме специально решено, что первые символы являются "ультра"уникальными и никогда не будут конфликтовать с другими подобными хэшами, или алгоритм генерирует каждую часть хэша таким же образом?
2 ответов
Git использует следующую информацию для создания sha-1:
- исходное дерево фиксации (которое распутывается на все поддеревья и blobs)
- Родительский commit sha1
- информация об авторе
- коммитер информация (верно: это разные вещи!)
- фиксация
(о полном объяснении; посмотрите здесь).
Git не гарантия, что первые 4 символа будут уникальными. В Глава 7 книги Pro Git написано:
Git может выяснить короткую, уникальную аббревиатуру для ваших значений SHA-1. Если вы передадите --abbrev-commit команде git log, вывод будет используйте более короткие значения, но сохраняйте их уникальными; по умолчанию используется семь символы, но делает их длиннее, если необходимо сохранить SHA-1 недвусмысленно:
поэтому Git просто делает аббревиатуру as сколько нужно до сих пор остаются уникальными. Они даже отмечают, что:
Как правило, от восьми до десяти символов более чем достаточно, чтобы быть уникальным в рамках проекта.
в качестве примера, ядро Linux, которое является довольно большим проектом с более 450k коммитов и 3,6 миллиона объектов, не имеет двух объектов, чьи SHA-1s перекрывают более первых 11 символов.
Так что на самом деле они просто зависят от великого невероятность иметь то же самое (X первых символов a) sha.
Apr. 2017: остерегайтесь, что после всего разрушен.IO эпизод (где столкновение SHA1 было достигнуто Google), 20-байтовый формат не будет там навсегда.
первым шагом для этого является замена unsigned char sha1[20]
который является жестким кодом по всей кодовой базе Git общим объектом, определение которого может измениться в будущем (SHA2?, Blake2, ...)
посмотреть совершить e86ab2c (21 Feb 2017) by Брайан м. Карлсон (bk2204
).
преобразовать остальные виды использования
unsigned char [20]
tostruct object_id
.
это пример постоянных усилий, начатых с совершить 5f7817c (13 Mar 2015) by Брайан м. Карлсон (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 первых символа больше не достаточно, чтобы гарантировать уникальность, как я объясняю в "сколько ГИТ ша это вообще считается необходимым однозначно идентифицировать изменение в данной кодовой базе?".
Обновление Декабря. 2017 с Git 2.16 (Q1 2018): эти усилия по поддержке альтернативного SHA продолжаются: см."почему Git не использует более современный SHA?".
вы сможете использовать другой хэш: SHA1 больше не является единственным для Git.