В чем разница между git-worktree и git-subtree? - PullRequest
0 голосов
/ 11 февраля 2019

В тот момент, когда я думал, что Git не может быть более сложным, я просто обнаружил, что git worktree.Либо это синоним поддерева, либо функция, о которой я никогда не знал.Является ли worktree тем же, что и поддерево, или они разные.Если они разные, чем они отличаются и какую проблему решает worktree?

Ответы [ 2 ]

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

Это очень разные.Чтобы понять их правильно, давайте определим рабочее дерево (или "рабочее дерево" или "рабочее дерево" или почти любой вариант этих написаний) относительно индекса и коммиты .

Вы уже знаете, что коммиты сохраняют моментальные снимки, и что каждый коммит имеет уникальный идентификатор хеша, который называет этот конкретный коммит.Для этого же коммита может быть много других имен (например, имен веток и / или тегов), но есть только один хэш-идентификатор.Вы, вероятно, также знаете, что в коммитах есть метаданных: , кто их создал (имя и адрес электронной почты), когда (метка времени) и почему (сообщение для git log, которое нужно показать).У каждого коммита также есть родительский хэш-идентификатор, или, точнее, список родителей, обычно только с одной записью.Родитель - это коммит, который приходит непосредственно перед этим, так что Git может пройти через цепочку коммитов, чтобы показать вещи с течением времени.(Коммит, имеющий два родительских хеш-идентификатора, является коммитом слияния . Коммит с нет родительским хеш-идентификатором является корневым коммитом , и есть по крайней мере один влюбой непустой репозиторий, так как первый сделанный коммит не имеет коммитов до него.)

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

Это означает, что все файлы, хранящиеся внутри любогокоммит заморожен.Они также сжаты в специальный формат только для Git, который может прочитать только Git.Это отлично подходит для истории , но как мы сможем выполнить какую-либо работу?Вот где рабочее дерево входит в картинку.

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

между текущим коммитом (выбранным однако) и рабочим деревом.поэтому две копии каждого файла: замороженная копия в коммите и полезная в рабочем дереве.

Git может остановиться здесь, и другие системы контроля версий, такие как Mercurial(см. ) сделать именно это.Но по разным причинам - многие из них имеют отношение к «иди очень быстро» - Git добавляет третью копию каждого файла.Эта третья копия входит в то, что Git называет, по-разному, index , staging area или cache .(Какое имя вы видите, зависит от того, кто или какая часть Git выполняет вызов.) Файлы в индексе в основном имеют ту же форму, что и в коммитах, за исключением того, что в индексе они не замораживали.Они более готовы к «заморозке» или «слякотно», если хотите.

Индекс также сохраняет вкладки на рабочем дереве, так что они тесно спарены: индекс «знает», что находится врабочее дерево, или если нет, - если аспект кэша индекса устарел - он знает , что , что помогает Git быстро выяснить, что изменилось, если что-нибудь произошло.Более того, когда вы запускаете git commit, Git на самом деле даже не смотрит на рабочее дерево (за исключением добавления некоторых комментариев к файлу, который вы редактируете для своего сообщения журнала).Он просто замораживает готовые к использованию файлы из индекса, где индекс получает свое имя промежуточная область , чтобы сделать новый коммит.

В конце концов, когда вывы работаете с коммитом в Git, у вас есть три активных копий в любое время:

  • HEAD коммит копия заморожена и доступна только в Git.
  • Индекс сотрудничестваПи слякотный: только для мерзавцев, но не совсем замороженный.Первоначально он совпадает с копией HEAD, но вы можете перезаписать его с помощью git add.
  • Копия рабочего дерева нормальная и плавная, и вы можете делать с ней все что угодно.

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

Это оставляет нас сПроблема, которую нужно решить: что, если во время работы над чем-то нам нужно срочно исправить какую-то ошибку в какой-то ветке другой ?Мы могли бы сделать еще один клон, и это был традиционный ответ.Если мы не находимся в середине конфликтующего слияния, мы могли бы использовать git stash;это был другой ответ.Одно не очень удовлетворительно, а другое бесполезно, если мы находимся в середине слияния.

Итак, введите git worktree add.Используя git worktree add, вы можете добавить еще одну пару индекса и рабочего дерева в ваш существующий репозиторий.Есть одно очень сильное ограничение (по уважительной причине, зависящее от реализации): каждое добавленное рабочее дерево должно быть на своей собственной ветке , или же использовать режим «отсоединенного HEAD».То есть, если ваше основное рабочее дерево находится на ветке feature/short, никакое добавленное рабочее дерево не может использовать эту ветку.Они могут использовать master или hotfix или develop, но не feature/short.(Или они могут использовать отдельный HEAD при любом коммите в любом месте репозитория.)

Когда вы закончите с любым из добавленных вторичных рабочих деревьев, вы можете просто rm -rf it, а затемзапустите git worktree prune из одного из других вторичных рабочих деревьев или основного рабочего дерева, чтобы Git выполнял поиск и не находил добавленное рабочее дерево.Это «разблокирует» любую ветвь, к которой добавлено добавленное рабочее дерево.

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

( RomainValeri также упомянул стратегию слияния git-merge-subtree , которая является сортировкойотносится к git subtree в том смысле, что оно направлено на переименование поддерева в одном или двух из трех входов слияния.)

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

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

git worktree ( doc ) - правильная команда git (тогда как поддерево - Вклад , благодаря Крису за информацию ), которая в основном помогает вам управлять несколькими рабочими деревьями в одном репо с несколькими дополнительными подкомандами (list, add,и т.д.).

Принимая во внимание, что поддерево, помимо вышеупомянутого вклада, является одной из доступных стратегий слияния .

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

...