SHA-1 коммитов рассчитывается только на основе содержимого дерева? - PullRequest
10 голосов
/ 16 января 2012

Ради эксперимента, скажем, ваш git log идентифицирует следующие коммиты

commit 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438  // added 2nd file
commit 9188f9a25b045f130b08888bc3f638099fa7f212  // initial commit

После фиксации .git/refs/heads/master указывает на 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438.

Допустим, после этого я вручную редактирую файл .git/refs/heads/master, чтобы он указывал на 9188f9a25b045f130b08888bc3f638099fa7f212

На этом этапе git status распознает, что новый незафиксированный файл нуждается в некотором внимании. Это тот же файл, о котором раньше заботился мой второй коммит.

Если я сделаю это .. git log теперь показывает

commit b317f67686f9e6ab1eaabf47073b401d677205d5  // 2nd file committed for the 2nd time
commit 9188f9a25b045f130b08888bc3f638099fa7f212  // initial commit

Вопрос 1:

Вы заметите, что SHA хэши отличаются с самого первого раза, когда я записал второй файл, и сейчас. Это почему? Содержимое файла не изменилось, это все тот же файл.

Вопрос 2

В этот момент, что случилось с первоначальным вторым коммитом? Когда я делаю git show 16bc8486, это показывает этот коммит. Однако он не отображается в истории git log.

Ответы [ 3 ]

14 голосов
/ 16 января 2012

Вопрос 1: поскольку хеш генерируется с учетом всего, включая метаданные фиксации (который сам содержит дату и время).

Вопрос 2: git log показывает журнал текущей ветви.Коммит 16bc8486 не является его частью.Насколько я знаю (я не совсем уверен), сборщик мусора рано или поздно заберет его, если обнаружит, что ничего на него не ссылается (git gc --help) ..

6 голосов
/ 16 января 2012

Значения sha1 для каждого из файлов blobs будут идентичны в обоих случаях, если у вас одинаковое содержимое (даже если имя файла изменилось).

Аналогично значения sha1 для деревьев файлов с блобами будут одинаковыми, если они имеют одинаковые имена файлов.

Однако в самом верху у нас есть коммит , который будет содержать неизмененную ссылку на предыдущий коммит, верхнее дерево, автора и коммитера, но, как сказал KingCrunch, дата автора и коммиттера будет отличается , поэтому sha1 коммита sha1 будет другим.

Вы можете сделать их одинаковыми, если вы намеренно установили дату автора и коммиттера, используя переменные окружения, чтобы они не изменились.

2 голосов
/ 16 января 2012

SHA1 вычисляется из diff и всех метаданных этого коммита (включая автора и коммиттера, метку времени и другие данные).

По вашему второму вопросу фиксация данных все еще присутствует, но больше не является частью какой-либо живой ветки. Иногда git запускает сборку мусора, где фактически удаляются различные удаленные вещи. Вы заметите, что после того, как вы вручную запустите его, используя git gc, несвязанная фиксация исчезнет и больше не будет доступна для git show.

...