Что означает "дерево" в Git? - PullRequest
       1

Что означает "дерево" в Git?

0 голосов
/ 11 января 2019

Справочная страница git diff говорит это

ИМЯ

git-diff - Показать изменения между коммитами, коммитом и рабочим деревом и т. Д.

ОПИСАНИЕ

Показать изменения между рабочим деревом и индексом или деревом , изменениями между индексом и деревом , изменения между двумя деревьями , изменениями между двумя объектами BLOB-объектов или изменениями между двумя файлами на диске.

Означает ли "рабочее дерево" рабочий каталог?

Что здесь означает "дерево"? Это то же самое, что объект коммита или объект дерева? (Буквально, я думаю, что это означает объект дерева. Но я предполагаю, что он может иметь в виду объект фиксации, сравнивая часть «ОПИСАНИЕ» с частью «ИМЯ».)

Как указать "дерево" в качестве аргумента командной строки для git diff?

Если я могу также спросить, как вы указываете «объект blob» в качестве аргумента командной строки для git diff?

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Слово tree довольно перегружено в Git (ну, и, в общем, в вычислениях).

Рабочее дерево или Рабочее дерево (или другие варианты этого написания) относится к месту, в котором вы выполняете свою работу. Здесь файлы имеют свою обычную повседневную форму, доступны для чтения и записи с ОС. (В системе Unix, если вы chmod -w ваши файлы, вы не сможете их записать. Однако это не вина Git.)

A объект дерева в Git - это внутренняя структура данных, которая записывает дерево каталогов или поддерево. Он содержит одну запись для каждого файла или подкаталога (или, для подмодулей, запись gitlink для этого подмодуля). В каждой записи указан бит режима исполняемого файла, в виде флага «да» или «нет», который странным образом кодируется, 1 плюс имя файла и идентификатор хэша BLOB-объекта. Для поддерева в записи перечислены имя каталога и идентификатор хеша объекта поддерева. Затем Git может рекурсивно работать с объектом поддерева, чтобы найти больше файлов и еще больше поддеревьев по мере необходимости. Каждая запись в файле дает хэш-идентификатор для внутреннего blob объекта Git, который представляет собой замороженную (только для чтения) сжатую копию данных файла.

Каждый коммит сохраняет один (1) внутренний хэш-идентификатор объекта дерева Git. Этот объект дерева содержит снимок, который содержит коммит, поэтому снимок коммита действительно является одним из этих деревьев, которое содержит записи для файлов и поддеревьев. Поскольку каждый коммит имеет ровно одно дерево, Git может преобразовать спецификатор коммита в объект дерева:

$ git rev-parse master
3c31a203fbeedb4d746889dc77cbafc395fc6e92
$ git rev-parse master^{tree}
5c4b695f5d5606976f5b72e1a901ed17db30a359

В этом случае коммит , обозначенный master, является первым большим уродливым хешем, но внутренний объект tree , который этот коммит использует для хранения файлов, является вторым один.

Следовательно, рабочее дерево содержит реальные файлы с реальными данными, а объект дерева Git позволяет Git находить все замороженные файлы коммита, при условии, что вы дадите дерево объект, который соответствует некоторому коммиту. Команда git diff должна сравнивать две вещи. Эти две вещи могут быть либо двумя отдельными файлами - это своего рода вырожденный случай - либо двумя деревьями файлов . При сравнении двух деревьев, независимо от того, являются ли они объектами дерева или рабочим деревом, полным файлов, git diff будет:

  • Сравните файл Имена в каждом дереве.
  • Если они совпадают, Git предполагает, что это «один и тот же файл», и сравнивает содержимое файлов.
  • Если у них нет совпадающих имен, при необходимости попытайтесь сопоставить файлы по содержимому.
  • Если ничего не помогает, скажите, что некоторые файлы были удалены, а некоторые файлы добавлены. Содержимое удаленного файла все удаляются; содержимое добавленного файла полностью новое.

Это все еще только обзор, потому что git diff может сделать больше, чем просто эти вещи, но это основы.

Есть еще одна очень важная морщина: git diff может проверить индекс и рассматривать его как дерево. Индекс содержит копии файлов, взятых откуда-то. Это где-то изначально является тем, что вы делаете git checkout. Однако вы можете git add файлы из рабочего дерева, чтобы скопировать их в индекс, заменив версию, которая была там из фиксации. Вы можете git add файлы из рабочего дерева, которые никогда не были в коммите, и, таким образом, являются новыми для индекса. И вы можете git rm файлов, с или без --cached, взять файлы из индекса.

Поскольку Git создаст новый коммит из того, что находится в индексе во время выполнения git commit, сравнивая содержимое индекса с чем-либо - замороженным деревом из коммита или рабочим деревом - это действительно очень полезная вещь.


1 Фактические записи дерева хранилища (режим, путь, хэш) троек. mode - это строка: 100755 для исполняемого файла, 100644 для неисполняемого файла, 40000 для поддерева, 120000 для символической ссылки и 160000 для gitlink. Изначально это были поля stat st_mode в Linux, и Git допустил, например, 100664 для rw-rw-r--, но это оказалось ошибкой, поэтому в обычном дереве используется только одно из ограниченного подмножества. Git по-прежнему поддерживает 100664, поскольку могут существовать некоторые репозитории Git, у которых все еще есть такие записи, но если вы не найдете действительно старый репозиторий, вы не найдете 100664. Хеш всегда представляет собой хэш BLOB-объекта , за исключением для записей gitlink, где хеш-код - это требуемый хеш коммита в подмодуле.

0 голосов
/ 11 января 2019

Текущий рабочий каталог находится там, где думает ваша оболочка. Текущее рабочее дерево начинается в каталоге с репозиториями .git. Если в нем написано «рабочий каталог», вы можете подумать, что он перемещается, когда вы это делаете - это не так.

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

Но чтобы выполнить задачу, о которой вы просите, я обычно использую подпись в строке журнала конкретного коммита. Если это текущий коммит, то скажите «HEAD» или название вашей ветви. Если это глава другой ветки, то название этой ветки может работать. Если он помечен, имя тега работает. Также есть HEAD ^ 1 для предыдущего коммита.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...