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

Другие вопросы по тегам