Подтвердить что ты не робот

Git хранить информацию о различиях в объектах фиксации?

В соответствии с этим:

Важно отметить, что это сильно отличается от большинства SCM     системы, с которыми вы можете быть знакомы. Subversion, CVS, Perforce,     Mercurial и тому подобное используют системы хранения Delta - они хранят     различия между одной фиксацией и следующей. Git не делает     это - он хранит моментальный снимок того, что все файлы в вашем проекте     выглядят в этой древовидной структуре каждый раз, когда вы совершаете. Это     очень важная концепция для понимания при использовании Git.

Но когда я запустил git show $SHA1ofCommitObject...

commit 4405aa474fff8247607d0bf599e054173da84113
Author: Joe Smoe <[email protected]>
Date:   Tue May 1 08:48:21 2012 -0500

    First commit

diff --git a/index.html b/index.html
new file mode 100644
index 0000000..de8b69b
--- /dev/null
+++ b/index.html
@@ -0,0 +1 @@
+<h1>Hello World!</h1>
diff --git a/interests/chess.html b/interests/chess.html
new file mode 100644
index 0000000..e5be7dd
--- /dev/null
+++ b/interests/chess.html
@@ -0,0 +1 @@
+Did you see on Slashdot that King Gambit accepted is solved! <a href="#" onclick="location.href='http://game

... он выводит разницу фиксации с предыдущими фиксациями. Я знаю, что Git не хранит diff в объектах blob, но сохраняет ли он diff в объектах commit? Или git show динамически вычисляет diff?

'; return false;
4b9b3361

Ответ 1

Нет, объекты фиксации в git не содержат diffs - вместо этого каждый объект commit содержит хэш дерева, который рекурсивно и полностью определяет содержимое исходного дерева при этой фиксации. Там приятное объяснение в сообществе сообщества git того, что входит в объекты blob, древовидные объекты и объекты фиксации.

Все отличия, которые показываются вам инструментами git, рассчитываются по запросу из полного содержимого файлов.

Ответ 2

Что означает утверждение, так это то, что большинству других систем управления версиями в прошлом нужна точка отсчета, чтобы иметь возможность повторно создать текущую фиксацию.

Например, в какой-то момент в прошлом система VCS (система контроля версий), основанная на diff, сохранила бы полный моментальный снимок:

x = snapshot
+ = diff
History:
x-----+-----+-----+-----(+) Where we are now

Итак, в таком сценарии, чтобы заново создать состояние в (сейчас), ему нужно будет проверить (x), а затем применить diff для каждого (+), пока он не достигнет этого. Обратите внимание, что было бы крайне неэффективно хранить дельта навсегда, поэтому каждый так часто дельта-основанные VCSes сохраняют полный моментальный снимок. Вот как это делается для subversion.

Теперь git отличается. git хранит ссылки на полные капли, а это означает, что при git, достаточно только одного фиксации, чтобы воссоздать кодовую базу в этот момент времени. git не нужно искать информацию из прошлых версий для создания моментального снимка.

Итак, если это так, то где же происходит дельта-сжатие, которое использует git?

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

Однако, когда git запускает свою сборку мусора (или когда вы вызываете git gc вручную), дубликаты очищаются и создается файл только для чтения. Вам не нужно беспокоиться о запуске сборки мусора вручную - git содержит эвристику, которая сообщает, когда это делается.