Ответ 1
Git 2.5 предлагает с июля 2015 года замену contrib/workdir/git-new-workdir
: git worktree
См. Коммит 68a2e6a Джунио С. Хамано (gitster
).
В примечании к выпуску упоминается:
Замена для
contrib/workdir/git-new-workdir
, который не опирается на символические ссылки и делает совместное использование объектов и ссылок более безопасным, так как заемщики и заемщики знают друг о друге.
Смотрите коммит 799767cc9 (Git 2.5rc2)
Это означает, что теперь вы можете добавить git worktree add <path> [<branch>]
Создать
<path>
и оформить<branch>
в него. Новый рабочий каталог связан с текущим репозиторием, разделяя все, кроме определенных для рабочего каталога файлов, таких как HEAD, index и т.д. В разделеgit worktree
добавлено:Git-репозиторий может поддерживать несколько рабочих деревьев, что позволяет вам проверять более одной ветки за раз.
Сgit worktree add
новое хранилище связывается с репозиторием.Это новое рабочее дерево называется "связанным рабочим деревом", а не "основным рабочим деревом", подготовленным "
git init
" или "git clone
".
Репозиторий имеет одно основное рабочее дерево (если это не пустой репозиторий) и ноль или более связанных рабочих деревьев.подробности:
Каждое связанное рабочее дерево имеет собственную директорию sub -d в каталоге репозитория
$GIT_DIR/worktrees
.
Имя директории private sub -d обычно является базовым именем пути связанного рабочего дерева, возможно, с добавлением номера, чтобы сделать его уникальным.
Например, когда$GIT_DIR=/path/main/.git
командаgit worktree add/path/other/test-next next
создает:
- связанное рабочее дерево в
/path/other/test-next
и- также создает
$GIT_DIR/worktrees/test-next
(или$GIT_DIR/worktrees/test-next1
еслиtest-next
уже$GIT_DIR/worktrees/test-next1
).В связанном рабочем дереве:
$GIT_DIR
установлен, чтобы указывать на этот личный каталог (например,/path/main/.git/worktrees/test-next
в примере) и$GIT_COMMON_DIR
установлен так, чтобы указывать на основное рабочее дерево$GIT_DIR
(например,/path/main/.git
).Эти настройки выполняются в файле
.git
расположенном в верхней директории связанного рабочего дерева.Когда вы закончите со связанным рабочим деревом, вы можете просто удалить его.
Административные файлы рабочего дерева в хранилище в конечном итоге будут удалены автоматически (см.gc.pruneworktreesexpire
вgit config
), или вы можете запуститьgit worktree prune
в основном или любом связанном рабочем дереве, чтобы очистить любые устаревшие административные файлы.
Предупреждение: все еще есть git worktree
"BUGS" git worktree
о котором нужно знать.
Поддержка подмодулей является неполной.
НЕ рекомендуется делать несколько проверок суперпроекта.
Примечание: с помощью git 2.7rc1 (ноябрь 2015 г.) вы можете составить список ваших рабочих деревьев.
См совершать bb9c03b, совершать 92718b7, совершают 5193490, совершают 1ceb7f9, совершают 1ceb7f9, совершают 5193490, совершают 1ceb7f9, совершают 1ceb7f9 (08 окт 2015), совершать 92718b7, совершать 5193490, совершают 1ceb7f9, совершают 1ceb7f9 (08 окт 2015), совершают 5193490, зафиксировать 1ceb7f9 (8 октября 2015 г.), зафиксировать 1ceb7f9 (08 октября 2015 г.) и передать ac6c561 (02 октября 2015 г.) Майклом Раппаццо (rappazzo
).
(Объединено Junio C Hamano - gitster
- в коммите a46dcfb, 26 октября 2015 г.)
worktree
: добавить команду 'list
''
git worktree list
' просматривает список рабочих деревьев и выводит подробную информацию о рабочем дереве, включая путь к рабочему дереву, текущую извлеченную ревизию и ветвь, а также, если рабочее дерево пустое.
$ git worktree list
/path/to/bare-source (bare)
/path/to/linked-worktree abcd1234 [master]
/path/to/other-linked-worktree 1234abc (detached HEAD)
Существует также опция формата фарфора.
Формат фарфора имеет строку для каждого атрибута.
- Атрибуты перечислены с меткой и значением, разделенным одним пробелом.
- Логические атрибуты (такие как "bare" и "detached") перечислены только в качестве метки и присутствуют только в том случае, если значение равно true.
- Пустая строка указывает на конец рабочего дерева
Например:
$ git worktree list --porcelain
worktree /path/to/bare-source
bare
worktree /path/to/linked-worktree
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master
worktree /path/to/other-linked-worktree
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached
Примечание: если вы перемещаете папку рабочего дерева, вам необходимо вручную обновить файл gitdir
.
См. Коммит 618244e (22 января 2016 г.) и коммит d4cddd6 (18 января 2016 г.) Нгуеном Тай pclouds
Дуй (pclouds
).
Помогает: Эрик Саншайн (sunshineco
).
(Объединено с Junio C Hamano - gitster
- в коммите d0a1cbc, 10 февраля 2016 г.)
Новый документ в git 2.8 (март 2016 года) будет включать:
Если вы перемещаете связанное рабочее дерево, вам необходимо обновить файл '
gitdir
' в каталоге ввода.
Например, если связанное рабочее дерево перемещено в/newpath/test-next
и его файл.git
указывает на/path/main/.git/worktrees/test-next
, то обновите/path/main/.git/worktrees/test-next/gitdir
для ссылки/newpath/test-next
.
Будьте осторожны при удалении ветки: до git 2.9 (июнь 2016 года) вы могли удалить одну из используемых веток в другом рабочем дереве.
Когда
git worktree
функция "git worktree
", "git branch -d
" позволяла удалить ветку, которая была извлечена в другом рабочем дереве.
См. Коммит f292244 (29 марта 2016 г.) Казуки Ямагучи (rhenium
).
Помогает: Эрик Саншайн (sunshineco
).
(Объединено Junio C Hamano - gitster
- в коммите 4fca4e3, 13 апреля 2016 г.)
branch -d
: отказать в удалении ветки, которая в данный момент извлеченаКогда ветка проверяется текущим рабочим деревом, удаление ветки запрещено.
Однако, когда ветвь проверяется только другими рабочими деревьями, удаление некорректно завершается успешно.
Используйтеfind_shared_symref()
чтобы проверить, используется ли ветвь, а не просто сравнивать с текущим рабочим деревом HEAD.
Точно так же до git 2.9 (июнь 2016 г.) переименование ветки, отмеченной в другом рабочем дереве, не корректировало символический заголовок в другом рабочем дереве.
См. Коммит 18eb3a9 (08 апреля 2016 г.) и коммит 70999e9, коммит 2233066 (27 марта 2016 г.) Казуки Ямагучи (rhenium
).
(Объединено Junio C Hamano - gitster
- в коммите 741a694, 18 апреля 2016 г.)
branch -m
: обновить все заголовки для каждого рабочего дереваПри переименовании ветки в настоящее время обновляется только заголовок текущего рабочего дерева, но он должен обновлять заголовки всех рабочих деревьев, которые указывают на старую ветвь.
Это текущее поведение, /path/to/wt HEAD не обновляется:
% git worktree list
/path/to 2c3c5f2 [master]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m master master2
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 2c3c5f2 [oldname]
% git branch -m oldname newname
% git worktree list
/path/to 2c3c5f2 [master2]
/path/to/wt 0000000 [oldname]
Этот патч исправляет эту проблему, обновляя все соответствующие заголовки рабочего дерева при переименовании ветки.
Механизм блокировки официально поддерживается git 2.10 (3 квартал 2016 г.)
См. Коммит 080739b, коммит 6d30862, коммит 58142c0, коммит 346ef53, коммит 346ef53, коммит 58142c0, коммит 346ef53, коммит 346ef53 (13 июня 2016 г.) и коммит 984ad9e, коммит 6835314 (03 июня 2016 г.) от pclouds
Thái Ngọc Duy (pclouds
).
Предложил: Эрик Саншайн (sunshineco
).
(Объединено Junio C Hamano - gitster
- в коммите 2c608e0, 28 июля 2016 г.)
git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>
Если связанное рабочее дерево хранится на переносном устройстве или общем сетевом ресурсе, который не всегда монтируется, вы можете предотвратить
git worktree lock
его административных файлов,git worktree lock
командуgit worktree lock
, дополнительно указав--reason
чтобы объяснить, почему рабочее дерево заблокировано.,
<worktree>
: если последние компоненты пути в пути рабочего дерева уникальны среди рабочих деревьев, его можно использовать для идентификации рабочих деревьев.
Например, если вам нужно только рабочие деревья в "/abc/def/ghi
" и "/abc/def/ggg
", то "ghi
" или "def/ghi
" достаточно, чтобы указать на предыдущее рабочее дерево.
В Git 2.13 (второй квартал 2017 года) добавлена опция lock
в коммите 507e6e9 (12 апреля 2017 года) от Nguyễn Thái Ngọc Duy (pclouds
).
Предложил: Дэвид Тейлор (dt
).
peff
: Джефф Кинг (peff
).
(Объединено Junio C Hamano - gitster
- в коммите e311597, 26 апреля 2017 г.)
Разрешить заблокировать рабочее дерево сразу после его создания.
Это помогает предотвратитьgit worktree add; git worktree lock
между "git worktree add; git worktree lock
" и "git worktree prune
".
Итак, git worktree add' --lock
является эквивалентом git worktree lock
git worktree add
после git worktree add
, но без условия гонки.
Git 2. 17+ (Q2 2018) добавляет git worktree move
git worktree remove
/git worktree remove
: см. Этот ответ.
В Git 2.19 (Q3 2018) добавлена опция " --quiet
", чтобы сделать " git worktree add
" менее многословным.
См. Коммит 371979c (15 августа 2018 г.) Элии Пинто (devzero2000
).
При поддержке: Мартин Агрен, Дуй Нгуен (pclouds
) и Эрик Саншайн (sunshineco
).
(Объединено с Junio C Hamano - gitster
- в коммите a988ce9, 27 августа 2018 г.)
worktree
: добавить--quiet
Добавьте опцию '
--quiet
' вgit worktree
, как и для других командgit
.
"add
" - единственная команда, на которую она влияет, поскольку все остальные команды, кроме "list
", в настоящее время по умолчанию молчат.
Обратите внимание, что " git worktree add
" используется для "поиска доступного имени с помощью stat, а затем mkdir
", которое склонно к гонке.
Это было исправлено в Git 2.22 (Q2 2019) с использованием mkdir
и реакцией на EEXIST
в цикле.
См. Коммит 7af01f2 (20 февраля 2019 г.) Михала Суханека (hramrach
).
(Объединено Junio C Hamano - gitster
- в коммите 20fe798, 09 апреля 2019 г.)
worktree
: исправитьworktree add
расуGit запускает цикл статистики, чтобы найти доступное имя рабочего дерева, а затем выполняет
mkdir
для найденного имени.
Включите его в циклmkdir
чтобы избежать повторного вызова worktree, добавьте поиск того же свободного имени и сначала создание каталога.
Git 2.22 (Q2 2019) исправляет логику, чтобы сказать, имеет ли хранилище Git рабочее дерево, защищает " git branch -d
" от удаления ветки, которая в настоящий момент извлечена по ошибке.
Реализация этой логики была нарушена для репозиториев с необычным именем, что, к сожалению, является нормой для подмодулей в наши дни.
См. Коммит f3534c9 (19 апреля 2019 г.) Джонатана Тана (jhowtan
).
(Объединено Junio C Hamano - gitster
- в коммите ec2642a, 08 мая 2019 г.)
Code Pull запрашивает 178 идей
worktree
: обновлениеis_bare
эвристикиКогда
git branch -d <name>
"git branch -d <name>
", Git обычно сначала проверяет, извлечена ли эта ветка в данный момент.
Но эта проверка не выполняется, если каталог Git этого репозитория находится не в "<repo>/.git
", что имеет место, если этот репозиторий является подмодулем, в котором его каталог Git хранится как "super/.git/modules/<repo>
", например.
Это приводит к удалению ветки, даже если она извлечена.Это связано с тем, что
get_main_worktree()
вworktree.c
устанавливаетis_bare
для рабочего дерева только с использованием эвристики, согласно которой репо является пустым, если путь к рабочему дереву не заканчивается в "/.git
", и иначе не оголяется.
Этот кодis_bare
был введен в 92718b7 ("worktree
: добавить детали в структуру worktree", 2015-10-08, Git v2.7.0-rc0), следуя эвристикеpre-core.bare
.Этот патч делает 2 вещи:
- Научите
get_main_worktree()
вместо этого использоватьis_bare_repository()
, представленную в 7d1864c ("Представьте переменную конфигурации is_bare_repository() и core.bare", 2007-01-07, Git v1.5.0-rc1) и обновлена в e90fdc3 ("Очистить работу"). обработка дерева ", 2007-08-01, Git v1.5.3-rc4).
Это решает проблему "git branch -d <name>
", описанную выше.Однако... Если репозиторий имеет
core.bare=1
но команда "git
" запускается с одного из его вторичных рабочих деревьев,is_bare_repository()
возвращает false (что нормально, поскольку доступно рабочее дерево).И, рассматривая основное рабочее дерево как непокрытое, когда оно голое, вызывает проблемы:
Например, ошибка удаления ветки из вторичного рабочего дерева, на которую ссылается главный заголовок рабочего дерева, даже если это основное рабочее дерево пустое.
Чтобы избежать этого, также проверьте
core.bare
при установкеis_bare
.
Еслиcore.bare=1
, доверяйте ему, а в противном случае используйтеis_bare_repository()
.