Как 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] to struct 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.