В филиалах нет рабочих наборов. (Ну, может быть, они и делают, так как вы не определили рабочий набор , но Git также не определяет рабочий набор. Но так как я не знаю, что вы имеете в виду, я использую рабочий набор в качестве псевдонима для рабочего дерева , которое является четко определенным, а ветви не имеют рабочих деревьев.)
Что делают имена веток, это выбирают один конкретный коммит. Этот коммит затем имеет некоторый родительский коммит (или более одного, если это слияние); родитель имеет своего родителя и так далее, образуя цепочку коммитов. В результате мы можем сказать, что ветвь (или имя ветки) содержит некоторый набор коммитов: это коммиты, которые достижимы из имени. Хорошее введение во все это см. Думай как (а) Git .
Каждый коммит имеет сохраненное дерево или снимок. Как вы обнаружили, git diff-tree
- это так называемая сантехническая команда (рабочая лошадка, способная работать со скриптами) для сравнения двух деревьев, найденных в двух коммитах:
git diff-tree -r commit1 commit2
рекурсивно сравнивает все деревья (-r
), сравнивая все файлы, содержащиеся в двух снимках. Вы можете записать это по буквам commit1..commit2
: это означает то же самое, используйте commit1
в качестве левой стороны и commit2
в качестве правой стороны в сравнении. Результатом этого сравнения является, по сути, последовательность инструкций, например, добавляет несколько строк в этот файл, удаляет некоторые строки из этого, и вы заставите дерево, присоединенное к commit1
, соответствовать дереву, присоединенному к commit2
.
Вы можете добавить опции, такие как --name-only
или --name-status
и --find-renames
с необязательным значением индекса сходства в процентах, чтобы Git вычислял места, где переименование, а затем изменение, файл производит более короткая последовательность команд, чем простой , удалите файл A и создайте новый файл B с нуля с этим содержимым . Например, возможно, более короткая последовательность - , переименуйте A в B, затем удалите строку 17, , что явно намного короче, чем , удалите файл A, затем создайте файл B с этими 10000 строк: [очень длинный список линий] .
Действующая, ориентированная на пользователя, команда git diff
в действительности запускает git diff-tree
или git diff-index
или что-то еще, но с учетом конфигурации пользователя (например, diff.renames
и diff.renameLimit
) и с выводом отправляется через пейджер , раскрашен и т. д. Git называет эти команды фарфор , поскольку они должны быть удобными для пользователя (против сантехники, скрытой за стенами, вне поля зрения).
Когда вы делаете новый коммит, у вас в Git сохраняется новый снимок. Git создает новый снимок из того, что Git имеет в своем index во время запуска git commit
. parent нового коммита - это старая вершина текущей ветви; новый коммит становится кончиком текущей ветви. Так растут ветви.
Различные команды, которые вы используете, такие как git rm
или git add
, работают с index . Вы используете git checkout <em>branch</em>
для извлечения коммитов веток в этот индекс. Файлы, хранящиеся в в индексе, трудно увидеть - вы можете получить полный список с git ls-files --stage
, но это редко очень полезно. Эти файлы, в индексе и (в конечном итоге) замороженные в коммите, все равно находятся в специальной форме Git. Таким образом, чтобы работать с этими файлами, когда у вас есть Git, извлекающий коммит-коммит, у вас также есть Git, извлекающий все файлы в рабочее дерево .
Рабочее дерево содержит эти файлы в их обычном формате, где вы и ваш компьютер можете работать с ними обычными способами. Но все, что вы делаете в этом рабочем дереве, действительно нацелено на слияние с индексом, потому что это индекс, содержащий то, что входит в коммит next . Запуск git commit
упаковывает (замораживает) содержимое индекса в моментальный снимок и добавляет его в качестве новой подсказки ветви.
Следовательно, если вы сравниваете два коммита (с git diff
или git diff-tree
), затем вносите некоторые изменения в свой индекс и делаете новый коммит, то, что вы делаете, - это изменение своего индекса и использование его для создания нового коммита. Сравнение двух коммитов зависит от вас. Обратите внимание, что вы также можете сравнить любой один с вашего индекса, используя git diff --cached
(фарфор) или git diff-index --cached
(сантехника). И вы можете сравнивать индекс с рабочим деревом или коммит с рабочим деревом, также используя эти команды.