Git 2.5 предлагает с июля 2015 года замену contrib/workdir/git-new-workdir
: рабочее дерево git
См. коммит 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
» .
Хранилище имеет одно основное рабочее дерево (если оно не пустое) и ноль или более связанных рабочих деревьев.
подробности:
Каждое связанное рабочее дерево имеет частный подкаталог в хранилище
$GIT_DIR/worktrees
каталог.
Имя частного подкаталога обычно является базовым именем пути связанного рабочего дерева, возможно, с добавлением номера, чтобы сделать его уникальным.
Например, когда $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
настроено так, чтобы указывать на этот частный каталог (например, /path/main/.git/worktrees/test-next
в примере) и
$GIT_COMMON_DIR
установлен так, чтобы указывать обратно на главное рабочее дерево $GIT_DIR
(например, /path/main/.git
).
Эти настройки выполняются в файле .git
, расположенном в верхнем каталоге связанного рабочего дерева.
Когда вы закончите со связанным рабочим деревом, вы можете просто удалить его.
Административные файлы рабочего дерева в хранилище в конечном итоге будут удалены автоматически (см. gc.pruneworktreesexpire
в git config
), или вы можете запустить git worktree prune
в основном или любом связанном рабочем дереве с
очистить все устаревшие административные файлы.
Предупреждение: все еще есть раздел git worktree
"ОШИБКИ" , о котором нужно знать.
Поддержка подмодулей не завершена .
НЕ рекомендуется делать несколько проверок суперпроекта.
Примечание: с помощью git 2.7rc1 (ноябрь 2015 г.) вы можете перечислить свои рабочие деревья.
См. commit bb9c03b , commit 92718b7 , commit 5193490 , commit 1ceb7f9 , commit 1ceb7f9 , commit 5193490 , commit 1ceb7f9 , commit 1ceb7f9 (08 октября 2015), commit 92718b7 , commit 5193490 , commit 1ceb7f9 , коммит 1ceb7f9 (08 октября 2015 г.), коммит 5193490 , коммит 1ceb7f9 (08 октября 2015 г.), коммит 1ceb7f9 (08 октября 2015 г.) и коммит ac6c561 (02 октября 2015 г.) Майкл Раппаццо (rappazzo
) .
(Объединено с Junio C Hamano - gitster
- в commit 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
) .
Помощник: Эрик Саншайн (sunshineco
) .
(Объединено с Junio C Hamano - gitster
- в commit 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 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 г.) от Казуки Ямагути (* 1285) *) .
(Объединено Junio C Hamano - gitster
- в коммит 741a694 , 18 апреля 2016 г.)
branch -m
: обновить все заголовки для каждого рабочего дерева
При переименовании ветви, в настоящее время только заголовок текущего рабочего дерева
обновляется, но он должен обновлять заголовки всех рабочих деревьев, которые указывают на
старая ветка.
Это текущее поведение, заголовок / path / to / wt не обновляется:
% 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
) .
Предложил: Эрик Саншайн (sunshineco
) .
(Объединено Junio C Hamano - gitster
- в коммит 2c608e0 , 28 июля 2016 г.)
git worktree lock [--reason <string>] <worktree>
git worktree unlock <worktree>
Если связанное рабочее дерево хранится на переносном устройстве или в сетевой папке
который не всегда монтируется, вы можете предотвратить его административные файлы
удаляется с помощью команды git worktree lock
, опционально
specifying --reason
, чтобы объяснить, почему рабочее дерево заблокировано.
<worktree>
: Если последние компоненты пути на пути рабочего дерева уникальны среди рабочих деревьев, его можно использовать для идентификации рабочих деревьев.
Например, если у вас есть только рабочие деревья на «/abc/def/ghi
» и «/abc/def/ggg
», то «ghi
» или «def/ghi
» достаточно, чтобы указать на прежнее рабочее дерево.
Git 2.13 (2 квартал 2017 года) добавить опцию lock
в коммит 507e6e9 (12 апреля 2017) Nguy Thn Thái Ngọc Duy (pclouds
) .
Предложил: Дэвид Тейлор (dt
) .
Помощник: Джефф Кинг (peff
) .
(Объединено Junio C Hamano - gitster
- в коммит e311597 , 26 апреля 2017 г.)
Разрешить блокировку рабочего дерева сразу после его создания.
Это помогает предотвратить гонку между "git worktree add; git worktree lock
" и
"git worktree prune
".
Таким образом, git worktree add' --lock
является эквивалентом git worktree lock
после git worktree add
, но без условия гонки.
Git 2.17+ (Q2 2018) добавляет git worktree move
/ 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
, чтобы избежать повторного вызова рабочего дерева. Добавьте поиск того же свободного имени и сначала создайте каталог.
Git 2.22 (Q2 2019) исправляет логику, чтобы сказать, имеет ли рабочее хранилище Git рабочее дерево, защищает "git branch -D
" от удаления ветви, которая в настоящий момент проверена
по ошибке.
Реализация этой логики была нарушена для репозиториев с необычным именем, что, к сожалению, является нормой для подмодулей в наши дни.
См. коммит f3534c9 (19 апреля 2019 г.) Джонатан Тан (jhowtan
) .
(Объединено с Junio C Hamano - gitster
- in commit ec2642a , 08 мая 2019 г.)
код
Потяните запросы 178
Insights
worktree
: обновление is_bare
эвристика
Когда запускается "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
: добавить детали в структуру рабочего дерева», 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 (что нормально, так как рабочее дерево доступно).
И если рассматривать основное рабочее дерево как непокрытое, когда оно голое, возникает проблема:
Например, ошибка удаления ветки из вторичного рабочего дерева, на которую ссылается HEAD основного рабочего дерева, даже если это основное рабочее дерево пустое.
Во избежание этого также проверьте core.bare
при настройке is_bare
.
Если core.bare=1
, доверяйте ему, а в противном случае используйте is_bare_repository()
.