git-worktree
Имя
git-worktree — управление несколькими рабочими деревьями
Краткое описание
git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]]
[--orphan] [(-b | -B) <new-branch>] <path> [<commit-ish>]
git worktree list [-v | --porcelain [-z]]
git worktree lock [--reason <string>] <worktree>
git worktree move <worktree> <new-path>
git worktree prune [-n] [-v] [--expire <expire>]
git worktree remove [-f] <worktree>
git worktree repair [<path>…]
git worktree unlock <worktree> Описание
Управление несколькими рабочими деревьями, связанными с одним репозиторием.
Репозиторий Git может поддерживать несколько рабочих деревьев, что позволяет одновременно извлечь более одной ветки. С помощью git worktree add с репозиторием связывается новое рабочее дерево, а также добавляются дополнительные метаданные, отличающие это рабочее дерево от других в том же репозитории. Рабочее дерево вместе с этими метаданными называется «рабочим деревом».
Это новое рабочее дерево называется «связанным рабочим деревом» в отличие от «основного рабочего дерева», подготовленного командами git-init[1] или git-clone[1]. У репозитория есть одно основное рабочее дерево (если это не bare-репозиторий) и ноль или более связанных рабочих деревьев. Когда связанное рабочее дерево больше не нужно, удалите его с помощью git worktree remove.
В простейшем случае git worktree add <path> автоматически создаёт новую ветку, имя которой совпадает с последним компонентом <path>; это удобно, если вы собираетесь работать над новой задачей. Например, git worktree add ../hotfix создаёт новую ветку hotfix и извлекает её в путь ../hotfix. Чтобы вместо этого работать с существующей веткой в новом рабочем дереве, используйте git worktree add <path> <branch>. Если же вы просто собираетесь внести некоторые экспериментальные изменения или провести тестирование, не затрагивая текущую разработку, часто удобно создать рабочее дерево throwaway, не связанное ни с одной веткой. Например, git worktree add -d <path> создаёт новое рабочее дерево с отделённым HEAD на том же коммите, что и текущая ветка.
Если рабочее дерево удалено без использования git worktree remove, связанные с ним административные файлы, расположенные в репозитории (см. раздел «ПОДРОБНОСТИ» ниже), в конечном итоге будут удалены автоматически (см. gc.worktreePruneExpire в git-config[1]). Также можно выполнить git worktree prune в основном или любом связанном рабочем дереве, чтобы удалить все устаревшие административные файлы.
Если рабочее дерево для связанного рабочего дерева находится на переносном устройстве или сетевом ресурсе, который не всегда подключён, можно предотвратить удаление его административных файлов, выполнив команду git worktree lock; при желании укажите --reason, чтобы объяснить, почему рабочее дерево заблокировано.
Команды
-
add<path> [<commit-ish>] -
Создаёт рабочее дерево по пути
<path>и извлекает в него<commit-ish>. Новое рабочее дерево связано с текущим репозиторием и использует общие данные, за исключением файлов, относящихся к отдельному рабочему дереву, таких какHEAD,indexи т. д. Для удобства<commit-ish>может быть простым «-», что равнозначно@{-1}.Если
<commit-ish>— это имя ветки (обозначим её<branch>), и такая ветка не найдена, а параметры-b,-Bи--detachне используются, но в единственном удалённом репозитории есть отслеживаемая ветка с таким же именем (обозначим её<remote>), команда действует так же, как:$ git worktree add --track -b <branch> <path> <remote>/<branch>
Если ветка существует в нескольких удалённых репозиториях и один из них указан в переменной конфигурации
checkout.defaultRemote, для устранения неоднозначности будет выбран именно он, даже если<branch>не является уникальным среди всех удалённых репозиториев. Например, задайте значениеcheckout.defaultRemote=origin, чтобы всегда извлекать удалённые ветки оттуда, если<branch>неоднозначно, но существует в удалённом репозиторииorigin. См. такжеcheckout.defaultRemoteв git-config[1].Если
<commit-ish>не указан и параметры-b,-Bи--detachне используются, то для удобства новое рабочее дерево связывается с веткой (обозначим её<branch>), названной по результату$(basename<path>). Если<branch>не существует, автоматически создаётся новая ветка на основеHEAD, как если бы был указан параметр-b<branch>. Если<branch>существует, она будет извлечена в новое рабочее дерево, если только она не извлечена где-либо ещё; в противном случае команда откажется создавать рабочее дерево (если не используется--force).Если
<commit-ish>не указан, параметры--detachи--orphanне используются, а допустимых локальных веток (или удалённых веток, если задан--guess-remote) нет, то для удобства новое рабочее дерево связывается с новой ещё не созданной веткой с именем<branch>(по результату$(basename<path>), если не используются параметры-bили-B), как если бы команде был передан параметр--orphan. Если в репозитории настроен удалённый репозиторий и используется--guess-remote, но удалённых или локальных веток нет, команда завершится с предупреждением о том, что сначала следует получить данные из удалённого репозитория (или переопределить поведение с помощью-f/--force). -
list -
Выводит сведения о каждом рабочем дереве. Сначала выводится основное рабочее дерево, затем каждое из связанных рабочих деревьев. В выводе указывается, является ли рабочее дерево bare, какая ревизия извлечена в данный момент, какая ветка извлечена (или «отделённый HEAD», если ветки нет), а также пометки «заблокировано», если рабочее дерево заблокировано, и «можно очистить», если команда
pruneможет удалить сведения о нём. -
lock -
Если рабочее дерево находится на переносном устройстве или сетевом ресурсе, который не всегда подключён, заблокируйте его, чтобы предотвратить автоматическое удаление административных файлов. Это также предотвращает перемещение или удаление рабочего дерева. При желании укажите причину блокировки с помощью
--reason. -
move -
Перемещает рабочее дерево в новое расположение. Обратите внимание, что основное рабочее дерево и связанные рабочие деревья, содержащие подмодули, нельзя переместить с помощью этой команды. Однако команда
gitworktreerepairможет восстановить связь со связанными рабочими деревьями, если переместить основное рабочее дерево вручную. -
prune -
Удаляет из
$GIT_DIR/worktreesсведения о рабочих деревьях, рабочие каталоги которых отсутствуют. Полезно после ручного удаления рабочего дерева, которое больше не требуется (но в следующий раз используйте для этого «git worktree remove»). Кроме того, если выmovedрабочее дерево в другое место, из-за чего сведения о нём стали устаревшими, см. «git worktree repair», чтобы восстановить связь с новым расположением рабочего дерева. -
remove -
Удаляет рабочее дерево. Можно удалить только чистые рабочие деревья (без неотслеживаемых файлов и изменений в отслеживаемых файлах). Грязные рабочие деревья и рабочие деревья с подмодулями можно удалить с помощью
--force. Основное рабочее дерево удалить нельзя. -
repair[<path>...] -
По возможности восстанавливает административные файлы рабочего дерева, если они были повреждены или устарели из-за внешних факторов.
Например, если основное рабочее дерево (или bare-репозиторий) перемещено, связанные рабочие деревья не смогут его найти. Выполнение команды
repairв основном рабочем дереве восстановит связь связанных рабочих деревьев с основным.Аналогично, если рабочее дерево для связанного рабочего дерева перемещено без использования
gitworktreemove, основное рабочее дерево (или bare-репозиторий) не сможет его найти. Выполнение командыrepairв недавно перемещённом рабочем дереве восстановит связь. Если перемещено несколько связанных рабочих деревьев, выполнитеrepairиз любого рабочего дерева, указав новые<path>каждого дерева в качестве аргументов, чтобы восстановить связь со всеми указанными путями.Если основное и связанные рабочие деревья были перемещены или скопированы вручную, выполните
repairв основном рабочем дереве и укажите новые<path>каждого связанного рабочего дерева, чтобы восстановить все связи в обоих направлениях. -
unlock -
Разблокирует рабочее дерево, разрешая его очистку, перемещение или удаление.
Параметры
-
-f -
--force -
По умолчанию
addотказывается создавать новое рабочее дерево, если<commit-ish>— это имя ветки, уже извлечённой в другом рабочем дереве, или если<path>уже назначен какому-либо рабочему дереву, но отсутствует (например, если<path>был удалён вручную). Этот параметр отключает эти меры защиты. Чтобы добавить отсутствующий, но заблокированный путь рабочего дерева, укажите--forceдважды.moveотказывается перемещать заблокированное рабочее дерево, если параметр--forceне указан дважды. Если целевой путь уже назначен другому рабочему дереву, но оно отсутствует (например, если<new-path>был удалён вручную),--forceпозволяет выполнить перемещение; если целевой путь заблокирован, укажите--forceдважды.removeотказывается удалять грязное рабочее дерево, если не указан параметр--force. Чтобы удалить заблокированное рабочее дерево, укажите--forceдважды. -
-b<new-branch> -
-B<new-branch> -
С параметром
addсоздаёт новую ветку с именем<new-branch>, начинающуюся с<commit-ish>, и извлекает<new-branch>в новое рабочее дерево. Если<commit-ish>не указан, по умолчанию используетсяHEAD. По умолчанию-bотказывается создавать новую ветку, если она уже существует.-Bотключает эту защиту, сбрасывая<new-branch>к<commit-ish>. -
-d -
--detach -
С параметром
addотделяетHEADв новом рабочем дереве. См. раздел «ОТДЕЛЁННЫЙ HEAD» в git-checkout[1]. -
--checkout -
--no-checkout -
По умолчанию
addизвлекает<commit-ish>, однако параметр--no-checkoutможно использовать, чтобы пропустить извлечение и выполнить настройку, например настроить разреженное извлечение. См. раздел «Разреженное извлечение» в git-read-tree[1]. -
--guess-remote -
--no-guess-remote -
При использовании
worktreeadd<path> без<commit-ish>, если в единственном удалённом репозитории есть отслеживаемая ветка, имя которой совпадает с последним компонентом<path>, новая ветка будет создана не на основеHEAD, а на основе этой удалённой отслеживаемой ветки; она будет указана как вышестоящая для новой ветки.Это поведение также можно сделать используемым по умолчанию с помощью параметра конфигурации
worktree.guessRemote. -
--relative-paths -
--no-relative-paths -
Связывает рабочие деревья с помощью относительных или абсолютных путей (по умолчанию). Переопределяет параметр конфигурации
worktree.useRelativePaths; см. git-config[1].С параметром
repairфайлы связей будут обновлены при несоответствии абсолютных и относительных путей, даже если связи корректны. -
--track -
--no-track -
При создании новой ветки, если
<commit-ish>является веткой, она указывается как вышестоящая для новой ветки. Это поведение используется по умолчанию, если<commit-ish>является удалённой отслеживаемой веткой. Подробнее см.--trackв git-branch[1]. -
--lock -
Оставляет рабочее дерево заблокированным после создания. Это равнозначно выполнению
gitworktreelockпослеgitworktreeadd, но без гонки. -
-n -
--dry-run -
С параметром
pruneничего не удаляет, а только сообщает, что было бы удалено. -
--orphan -
С параметром
addсоздаёт новое рабочее дерево и пустой индекс, связывая рабочее дерево с новой ещё не созданной веткой с именем<new-branch>. -
--porcelain -
С параметром
listвыводит данные в формате, удобном для разбора сценариями. Этот формат остаётся стабильным в разных версиях Git и независимо от пользовательской конфигурации. Рекомендуется использовать этот параметр вместе с-z. Подробнее см. ниже. -
-z -
Завершает каждую строку символом
NUL, а не переводом строки, когда--porcelainуказан вместе сlist. Это позволяет разбирать вывод, если путь рабочего дерева содержит символ перевода строки. -
-q -
--quiet -
С параметром
addподавляет информационные сообщения. -
-v -
--verbose -
С параметром
pruneсообщает обо всех удалениях.С параметром
listвыводит дополнительные сведения о рабочих деревьях (см. ниже). -
--expire<time> -
С параметром
pruneудаляет только отсутствующие рабочие деревья, если они старше<time>.С параметром
listпомечает отсутствующие рабочие деревья как подлежащие очистке, если они старше<time>. -
--reason<string> -
С параметром
lockили вместе сadd--lockуказывает причину блокировки рабочего дерева. - <worktree>
-
Рабочие деревья можно указать по относительному или абсолютному пути.
Если последние компоненты пути рабочего дерева уникальны среди всех рабочих деревьев, их можно использовать для его указания. Например, если у вас есть только два рабочих дерева —
/abc/def/ghiи/abc/def/ggg, — то для указания первого достаточноghiилиdef/ghi.
Ссылки
При использовании нескольких рабочих деревьев некоторые ссылки являются общими для всех рабочих деревьев, а другие относятся к отдельному рабочему дереву. Например, HEAD отличается для каждого рабочего дерева. В этом разделе описаны правила совместного использования и способы доступа к ссылкам одного рабочего дерева из другого.
В целом все псевдоссылки относятся к отдельному рабочему дереву, а все ссылки, начинающиеся с refs/, являются общими. Псевдоссылки — это такие ссылки, как HEAD, расположенные непосредственно в $GIT_DIR, а не внутри $GIT_DIR/refs. Однако есть исключения: ссылки внутри refs/bisect, refs/worktree и refs/rewritten не являются общими.
К ссылкам, относящимся к отдельному рабочему дереву, всё же можно получить доступ из другого рабочего дерева через два специальных пути: main-worktree и worktrees. Первый предоставляет доступ к ссылкам основного рабочего дерева, относящимся к отдельному рабочему дереву, а второй — к таким ссылкам всех связанных рабочих деревьев.
Например, main-worktree/HEAD или main-worktree/refs/bisect/good разрешаются в те же значения, что и HEAD и refs/bisect/good основного рабочего дерева соответственно. Аналогично, worktrees/foo/HEAD или worktrees/bar/refs/bisect/bad эквивалентны $GIT_COMMON_DIR/worktrees/foo/HEAD и $GIT_COMMON_DIR/worktrees/bar/refs/bisect/bad.
Для доступа к ссылкам лучше не просматривать содержимое $GIT_DIR напрямую. Вместо этого используйте такие команды, как git-rev-parse[1] или git-update-ref[1], которые корректно обрабатывают ссылки.
Файл конфигурации
По умолчанию файл config репозитория является общим для всех рабочих деревьев. Если в общем файле конфигурации заданы переменные core.bare или core.worktree, а extensions.worktreeConfig отключён, они будут применяться только к основному рабочему дереву.
Чтобы использовать конфигурацию, специфичную для рабочего дерева, можно включить расширение worktreeConfig, например:
$ git config extensions.worktreeConfig true
В этом режиме специальная конфигурация хранится по пути, указанному в git rev-parse --git-path config.worktree. Добавить или обновить конфигурацию в этом файле можно с помощью git config --worktree. Старые версии Git откажутся работать с репозиториями, в которых включено это расширение.
Обратите внимание, что в этом файле исключение для core.bare и core.worktree отсутствует. Если они есть в $GIT_DIR/config, их необходимо переместить в config.worktree основного рабочего дерева. Заодно можно проверить и переместить другие параметры конфигурации, которые не следует делать общими для всех рабочих деревьев:
-
core.worktreeникогда не следует делать общим. -
core.bareне следует делать общим, если его значение —core.bare=true. -
core.sparseCheckoutне следует делать общим, если только вы не уверены, что во всех рабочих деревьях всегда используется разреженное извлечение.
Подробнее см. документацию по extensions.worktreeConfig в git-config[1].
Подробности
Каждое связанное рабочее дерево имеет собственный подкаталог в каталоге репозитория $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, расположенном в корневом каталоге связанного рабочего дерева.
При разрешении путей с помощью git rev-parse --git-path используется либо $GIT_DIR, либо $GIT_COMMON_DIR в зависимости от пути. Например, в связанном рабочем дереве git rev-parse --git-path HEAD возвращает /path/main/.git/worktrees/test-next/HEAD (а не /path/other/test-next/.git/HEAD или /path/main/.git/HEAD), тогда как git rev-parse --git-path refs/heads/master использует $GIT_COMMON_DIR и возвращает /path/main/.git/refs/heads/master, поскольку ссылки общие для всех рабочих деревьев, за исключением refs/bisect, refs/worktree и refs/rewritten.
Дополнительную информацию см. в gitrepository-layout[5]. Как правило, не следует предполагать, относится ли путь к $GIT_DIR или $GIT_COMMON_DIR, если нужно напрямую получить доступ к чему-либо внутри $GIT_DIR. Используйте git rev-parse --git-path, чтобы получить конечный путь.
Если вы вручную переместили связанное рабочее дерево, необходимо обновить файл gitdir в каталоге этой записи. Например, если связанное рабочее дерево перемещено в /newpath/test-next, а его файл .git указывает на /path/main/.git/worktrees/test-next, обновите /path/main/.git/worktrees/test-next/gitdir, чтобы он указывал на /newpath/test-next. Ещё лучше запустить git worktree repair, чтобы автоматически восстановить связь.
Чтобы предотвратить удаление записи $GIT_DIR/worktrees (это может быть полезно в некоторых ситуациях, например, когда рабочее дерево записи хранится на переносном устройстве), используйте команду git worktree lock, которая добавляет в каталог записи файл с именем locked. В этом файле обычным текстом указана причина. Например, если файл .git связанного рабочего дерева указывает на /path/main/.git/worktrees/test-next, файл с именем /path/main/.git/worktrees/test-next/locked предотвратит удаление записи test-next. Подробнее см. в gitrepository-layout[5].
Если включён параметр extensions.worktreeConfig, файл конфигурации .git/worktrees/<id>/config.worktree считывается после .git/config.
Формат вывода списка
Команда worktree list поддерживает два формата вывода. В формате по умолчанию сведения отображаются в столбцах одной строки. Например:
$ git worktree list /path/to/bare-source (bare) /path/to/linked-worktree abcd1234 [master] /path/to/other-linked-worktree 1234abc (detached HEAD)
Команда также отображает аннотации для каждого рабочего дерева в соответствии с его состоянием. Возможны следующие аннотации:
-
locked, если рабочее дерево заблокировано. -
prunable, если рабочее дерево можно удалить с помощью командыgitworktreeprune.
$ git worktree list /path/to/linked-worktree abcd1234 [master] /path/to/locked-worktree acbd5678 (brancha) locked /path/to/prunable-worktree 5678abc (detached HEAD) prunable
Для этих аннотаций также может быть указана причина, которую можно увидеть в подробном режиме. В этом случае аннотация переносится на следующую строку с отступом, за ней следует дополнительная информация.
$ git worktree list --verbose
/path/to/linked-worktree abcd1234 [master]
/path/to/locked-worktree-no-reason abcd5678 (detached HEAD) locked
/path/to/locked-worktree-with-reason 1234abcd (brancha)
locked: worktree path is mounted on a portable device
/path/to/prunable-worktree 5678abc1 (detached HEAD)
prunable: gitdir file points to non-existent location Обратите внимание: если дополнительная информация доступна, аннотация переносится на следующую строку; в противном случае она остаётся в той же строке, что и само рабочее дерево.
Формат Porcelain
В формате Porcelain для каждого атрибута выводится отдельная строка. Если указан параметр -z, строки завершаются нулевым байтом, а не символом новой строки. Атрибуты перечисляются в виде метки и значения, разделённых одним пробелом. Логические атрибуты (например, bare и detached) выводятся только в виде метки и присутствуют, только если их значение равно true. Некоторые атрибуты (например, locked) могут выводиться только в виде метки или вместе со значением, в зависимости от наличия причины. Первым атрибутом рабочего дерева всегда является worktree; пустая строка обозначает конец записи. Например:
$ 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 worktree /path/to/linked-worktree-locked-no-reason HEAD 5678abc5678abc5678abc5678abc5678abc5678c branch refs/heads/locked-no-reason locked worktree /path/to/linked-worktree-locked-with-reason HEAD 3456def3456def3456def3456def3456def3456b branch refs/heads/locked-with-reason locked reason why is locked worktree /path/to/linked-worktree-prunable HEAD 1233def1234def1234def1234def1234def1234b detached prunable gitdir file points to non-existent location
Если не используется параметр -z, любые «нестандартные» символы в причине блокировки, например символы новой строки, экранируются, а вся причина заключается в кавычки, как описано для переменной конфигурации core.quotePath (см. git-config[1]). Например:
$ git worktree list --porcelain ... locked "reason\nwhy is locked" ...
Примеры
Вы находитесь в разгаре рефакторинга, когда заходит начальник и требует немедленно что-нибудь исправить. Обычно в такой ситуации можно воспользоваться командой git-stash[1], чтобы временно сохранить изменения, однако ваше рабочее дерево настолько захламлено (в нём есть новые, перемещённые и удалённые файлы и множество других разрозненных изменений), что вы не хотите рисковать и трогать что-либо в нём. Вместо этого вы создаёте временное связанное рабочее дерево, чтобы внести срочное исправление, удаляете его после завершения и затем возвращаетесь к прежнему сеансу рефакторинга.
$ git worktree add -b emergency-fix ../temp master $ pushd ../temp # ... hack hack hack ... $ git commit -a -m 'emergency fix for boss' $ popd $ git worktree remove ../temp
Конфигурация
Всё содержимое этого раздела ниже данной строки выборочно включено из документации git-config[1]. Здесь приведено то же содержимое, что и в ней:
-
worktree.guessRemote -
Если ветка не указана и не используется ни
-b, ни-B, ни--detach, тоgitworktreeaddпо умолчанию создаёт новую ветку от HEAD. Если параметруworktree.guessRemoteприсвоено значение true, командаworktreeaddпытается найти ветку удалённого отслеживания, имя которой однозначно совпадает с именем новой ветки. Если такая ветка существует, она переключается, а новая ветка настраивается как её «вышестоящая». Если найти такое совпадение не удаётся, создаётся новая ветка от текущегоHEAD. -
worktree.useRelativePaths -
Связывать рабочие деревья с помощью относительных путей (если задано значение «
true») или абсолютных путей (если задано значение «false»). Это особенно полезно в конфигурациях, где репозиторий и рабочие деревья могут перемещаться между разными расположениями или средами. По умолчанию используется значение «false».Обратите внимание: установка для
worktree.useRelativePathsзначения «true» подразумевает включение параметра конфигурацииextensions.relativeWorktrees(см. git-config[1]), что делает этот параметр несовместимым со старыми версиями Git.
Ошибки
Возможность одновременно извлекать несколько рабочих деревьев в целом всё ещё является экспериментальной, а поддержка подмодулей реализована не полностью. НЕ рекомендуется создавать несколько рабочих деревьев для суперпроекта.
worktree
© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/git-worktree