Для чего я буду использовать git-worktree?

211

Я прочитал пост Github на git-worktree . Они пишут:

Предположим, вы работаете в Git-репозитории над веткой, которая называется feature, когда пользователь сообщает об ошибке срочности master. Сначала вы создаете связанное рабочее дерево с новой веткой, hotfixизвлеченное относительно мастера […]. Вы можете исправить ошибку, нажать исправление и создать запрос на извлечение.

Когда я работаю над веткой с именем feature, и сообщается о какой-то серьезной ошибке в master, я обычно прячу все, над чем работаю, и создаю новую ветку. Когда я закончу, я смогу продолжить работу. Это очень простая модель, я работал так много лет.

С другой стороны, использование git-worktree имеет свои ограничения:

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

Почему я выбрал бы более сложный рабочий процесс для проблемы, которая уже была решена?

Есть ли что-то, git-worktreeчто нельзя было бы сделать заранее, и это оправдывает всю эту новую, сложную функцию?

awendt
источник
12
Одна вещь, которую вы не можете спрятать, - это незакрытые пути после слияния или перебазирования с конфликтами.
Чирлу
11
Если вы работаете с скомпилированными языками, сохранение означает, что вам придется перекомпилировать все, когда вы снимаете с диска.
mb14
У нас есть несколько различных продуктов, основанных на одном и том же (300 МБ) исходном коде, и я планирую объединить их все в одно большое репо и использовать рабочее дерево, чтобы хранить каждый продукт в отдельной папке, вместо того, чтобы иметь кучу огромных клоны, которые не синхронизированы
эндолит

Ответы:

197

Для меня git worktree - самое большое улучшение за долгое время. Я работаю в области разработки программного обеспечения для предприятий. Там очень часто приходится поддерживать старые версии, такие как выпущенные 3 года назад. Конечно, у вас есть ветка для каждой версии, чтобы вы могли легко переключиться на нее и исправить ошибку. Однако переключение обходится дорого, потому что вы полностью реструктурировали хранилище и, возможно, построили систему. Если вы переключитесь, ваша IDE начнет работать безумно, пытаясь адаптировать настройки проекта.

С worktree вы можете избежать этой постоянной реконфигурации. Оформите эти старые ветки в отдельных папках, используя рабочее дерево. Для каждой ветви вы получили независимый проект IDE.

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

Sebi
источник
4
Вам не нужно было получать одни и те же изменения из репо несколько раз. Вы могли бы просто скопировать каталог .git первого клона.
misiu_mp
1
@ jdk1.0 извините за путаницу, комментарий был направлен на misiu_mp
mxttie
2
Как человек, который использовал 2-3 реплик с высокой степенью репликации, чтобы я мог создавать одну ветвь функций при разработке на другой, у меня было каждое локальное репо как удаленное от других, и я полностью согласен с характеристиками Себи недостатков (много извлечения и подталкивания! Кроме того, как только я переключаюсь на рабочее дерево, я понимаю, что мне больше не нужно беспокоиться о расхождении локальных одноименных веток (что происходит примерно раз в 6-10 месяцев, так как меня несколько раз прерывали в течение дней и в итоге работает с одной и той же веткой функций из нескольких репозиториев, но не забудьте синхронизировать их обратно ...)
мудрец
3
@iheanyi - (1). Это быстрее, если IDE поддерживает внешние файлы данных (такие как базы данных индексации), связанные с данным каталогом. Если вы перебираете содержимое в одном и том же каталоге, это, как правило, делает недействительными любые кэши данных IDE, и для этого потребуется повторная индексация.
Стив Холлаш
5
@iheanyi - (2) Со временем история всего будет расти намного больше, чем файлы рабочего дерева в любой заданной точке. История всего == .gitкаталога. Со многими локальными клонами из апстрима у вас есть много локальных копий одной и той же базы данных, так как каждый клон имеет свою собственную .gitбазу данных. Со многими локальными рабочими деревьями каждое дерево использует одну и ту же .gitбазу данных. Да, если у вас есть локальные клоны вашего локального рабочего дерева, Git будет жестко связывать большую часть содержимого .git, но не в Windows.
Стив Холлаш
71

Я вижу некоторые варианты использования для этого.

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

Таким образом, git-worktreeя мог бы запустить вторую идею для другой ветки, выполняющей работу там.

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

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

Андреас Ведербранд
источник
6
Не будет git cloneработать так же хорошо для всех этих?
до
12
Но клонирование большого хранилища с удаленного компьютера может занять много времени. Я работаю против одного репозитория, который занимает несколько минут, чтобы клонировать. Я думаю, что вы могли бы сделать это с git clone --reference. Кроме того, управление всеми другими ветвями будет осуществляться только один раз, а не один раз для каждого рабочего каталога.
Андреас Ведербранд
6
Не клонируйте с пульта, клонируйте с вашего локального. Я не понимаю проблему управления филиалом, вы можете уточнить?
до
14
Я пытался использовать клонов, и действительно есть проблема управления. Вместо одного набора ветвей у меня есть набор клонов, которые я не могу увидеть все вместе в одном интерфейсе. Если мне нужно выбрать какие-то изменения, я должен выбрать или протолкнуть их. Это добавляет дополнительные шаги ко всем действиям. Все выполнимо, но всегда есть трения.
max630
2
И когда дело доходит до настройки резервного копирования, один репозиторий намного проще.
max630
64

Одним из очевидных применений является одновременное сравнение поведения (не исходного кода) разных версий - например, разных версий веб-сайта или просто веб-страницы.

Я попробовал это на месте.

  • создать каталог page1.

  • внутри создайте каталог srcи git initего.

  • в srcсоздании page1.htmlс небольшим содержанием и его фиксации.

  • $ git branch ver0

  • $ git worktree add ../V0 ver0

  • в srcмастер добавить текст page1.htmlи зафиксировать его.

  • $ git branch sty1

  • отредактируйте page1.htmlв sty1ветке (добавьте несколько отличительных стилей CSS) и добавьте коммит.

  • $ git worktree add ../S1 sty1

Теперь вы можете использовать веб-браузер, чтобы одновременно открывать и просматривать эти 3 версии:

  • ..\page1\src\page1.html // все, что git имеет как текущий

  • ..\page1\V0\page1.html // начальная версия

  • ..\page1\S1\page1.html // экспериментальная версия

RodMcGuire
источник
2
Я не понимаю, как это объясняет преимущество использования для этой цели worktree по сравнению с клоном.
iheanyi
@iheanyi Вы можете сказать то же самое о branch; Ответ также тот же: он легче и создан для работы.
OJFord
1
@OJFord, в этом вся суть. Этот ответ не объясняет мне, что делает worktree по-другому. Это явно не псевдоним ветки или клона, но эффект, который я здесь вижу, выглядит одинаково. Я не понимаю, насколько это легче, чем просто использовать ветку или клон.
iheanyi
@iheanyi Это отличается от использования ветвления - вы не можете использовать только ветки, чтобы получить несколько состояний рабочего дерева одновременно - и легче, чем второй (.., n-й) клон. Я имел в виду, что вы также можете сказать о ветке «почему бы не просто клонировать и внести свои изменения», но несколько веток в одном репо - это более легкий вес и более легко управляемый способ получить такое поведение.
OJFord
@OJFord Я не думаю, что это решает мою путаницу с рабочим деревом. Позвольте мне выразить это так, используете ли вы ветвь, клон или что-то еще, конечная цель описанного здесь процесса - сравнить три разные версии чего-либо одновременно. Исходя из того, что в ответе, я не понимаю, почему я бы использовал рабочее дерево вместо какой-то альтернативы. Ответ не объясняет, что делает worktree, а альтернативы нет. Вы утверждаете, что что-то более легкое (или более легкое), но я не понимаю, как рабочее дерево делает ветви менее «вескими».
iheanyi
29
  1. Существуют законные причины, по которым вам может потребоваться / нужно иметь несколько рабочих деревьев в файловой системе одновременно.

    • манипулирование извлеченными файлами при необходимости внесения изменений где-либо еще (например, компиляция / тестирование)

    • диффузия файлов с помощью обычных инструментов сравнения

    • во время конфликтов слияния я часто хочу перемещаться по исходному коду, так как он находится на стороне источника, при разрешении конфликтов в файлах.

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

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

  2. Некоторые люди спрашивают «почему бы не сделать несколько локальных клонов». Это правда, что с флагом --local вам не нужно беспокоиться о дополнительном использовании дискового пространства. Это (или похожие идеи) - то, что я сделал до этого момента. Функциональные преимущества связанных рабочих деревьев перед локальными клонами:

    1. С локальными клонами ваши дополнительные рабочие деревья (которые находятся в локальных клонах) просто не имеют доступа к исходной или восходящей ветвям. «Происхождение» в клоне не будет таким же, как «происхождение» в первом клоне.

      • Бег git log @{u}..или git diff origin/feature/other-featureможет быть очень полезным, и это либо невозможно, либо труднее. Эти идеи технически возможны для локальных клонов с помощью ассортимента обходных путей, но каждый обходной путь, который вы могли бы сделать, выполняется лучше и / или проще с помощью связанных рабочих дерев.
    2. Вы можете делиться ссылками между рабочими деревьями. Если вы хотите сравнить или позаимствовать изменения в другом местном филиале, теперь вы можете.

Александр Берд
источник
11
Также вы можете перечислить все рабочие деревья с помощью одной команды, с клонами, которые вы должны отслеживать их самостоятельно.
Ян Рингроз
хмм. Начиная с git 2.7.0 это похоже на случай. Приятно знать.
Александр Берд
9

tl; dr: Каждый раз, когда вы хотите, чтобы по каким-либо причинам одновременно проверялись два дерева работ, git-worktreeэто быстрый и экономичный способ сделать это.

Если вы создаете другое рабочее дерево, большинство частей репо (т.е. .git ) будет использоваться совместно, то есть если вы создадите ветку или получите данные, находясь в одном рабочем дереве, оно также будет доступно из любых других рабочих деревьев, которые у вас есть. Скажем, вы хотите запустить свой набор тестов на ветке foo, не нажимая его куда-нибудь, чтобы клонировать его, и вы хотите избежать хлопот с клонированием вашего репо локально, используя git-worktreeхороший способ создать просто новую проверку некоторого состояния в отдельное место, временно или постоянно. Как и в случае с клоном, все, что вам нужно сделать, когда вы покончили с ним, это удалить его, и ссылка на него через некоторое время будет собрана мусором.

jsageryd
источник
2
Документы говорят, что вы не можете иметь одну и ту же ветку в обеих рабочих копиях, что является серьезным ограничением. С Mercurial он работал только с небольшими проблемами.
Hyperww
Что вы можете. Страница руководства говорит как; искать --force. Но неудобно, если вы обновляете ветку в одном месте и ожидаете работать над ней в другом, поскольку рабочее дерево не обновляется.
jsageryd
Да, ветки в Mercurial являются более прозрачной концепцией в этом аспекте. Как ветви из одного рабочего дерева появляются в другом? Так же, как несколько ссылок? Мои первые эксперименты с рабочими деревьями, с запуском fetch в обоих, закончились двумя (!) Разными именами (!) Указателей origin/master.
Hyperww
Рабочее дерево - это (как следует из названия) просто рабочее дерево с некоторыми дополнительными функциями; хранилище распределяется между всеми рабочими деревьями. Единственное различие между двумя рабочими деревьями состоит в том, что извлеченная ветвь может быть (и для нормальных рабочих процессов) различной. Можно выполнить фиксацию в отдельном рабочем дереве, поэтому он также имеет свой собственный индекс (также называемый областью подготовки), чтобы сделать эту работу. .gitФайл в отдельном worktree представляет собой текстовый файл , содержащий путь к его конфигурации, которая находится в исходном хранилище.
jsageryd
2
@WilsonF: git checkout --ignore-other-worktrees <branch> git-scm.com/docs/git-checkout/…
jsageryd,
7

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

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

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

rethab
источник
4

У меня довольно необычный вопрос: я занимаюсь разработкой Windows и Linux на одной машине . У меня есть VirtualBox под управлением Linux внутри моей коробки Windows. VirtualBox монтирует некоторые каталоги Windows и использует их непосредственно внутри компьютера с Linux. Это позволяет мне использовать Windows для управления файлами, но строить в Linux. Это кроссплатформенный проект, поэтому он основан на Windows и Linux из одной и той же структуры каталогов.

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

В идеальном мире система сборки должна быть модифицирована таким образом, чтобы Windows и Linux могли сосуществовать в каталоге, но пока проблема решается с помощью рабочих деревьев. Папка «Linux» может генерировать специфичные для Linux артефакты сборки, а папка «Windows» может генерировать специфичные для Windows артефакты сборки. Хотя это вряд ли идеальное решение, оно создает хороший временный промежуток, ожидая устранения ошибок системы сборки.

По общему признанию, worktree не был разработан для этого; Я должен держать версию Windows и версию Linux в разных ветвях, хотя я действительно предпочел бы, чтобы они были в одной ветке. Тем не менее, это делает работу, и это несколько необычный случай, когда рабочее дерево спасает день.

AHelps
источник
+1 Это похоже на очень эффективный обходной путь для Make, не делающего исходных каталогов сборки для каждой конфигурации. У меня есть аналогичная установка VMware Workstation с гостями Ubuntu и macOS.
Tanz87
1

В новом проекте для меня я создал функцию. Но некоторые спецификации не удалось. Для сравнения результатов masterя создал work-treeрепо. Я шаг за шагом сравнивал результаты выполнения кода, пока не понял, что пошло не так.

itsnikolay
источник
Как рабочее дерево делает это проще, чем клон? Вопрос не в личных предпочтениях, а в конкретных различиях.
IInspectable
1

Я использую git worktreeдля развития машинного обучения.

У меня есть основной функциональный код, а затем я хочу разделить ветви разных экспериментов (разные алгоритмы и разные гиперпараметры). git worktreeпозволяет мне интегрировать dvc вместе с разными версиями моего кода, специализирующимися на разных алгоритмах. После выполнения всех учебных заданий я оцениваю итоговые метрики и объединяюсь, чтобы освоить лучшую отрасль / модель.

Рикардо М.С.
источник