git worktree
Команда git worktree позволяет переключаться между несколькими ветками одновременно без повторного клонирования. Примеры и разбор команд.
Что делает git worktree
Команда git worktree позволяет переключиться на несколько веток одновременно из одного репозитория. Каждое рабочее дерево (worktree) — это отдельный рабочий каталог со своей веткой и собственным индексом, но все они разделяют одно и то же хранилище объектов .git, историю, ссылки и конфигурацию. Это чистый способ работать с двумя ветками параллельно без необходимости дважды клонировать репозиторий.
Каталог, в который вы клонировали репозиторий, является основным рабочим деревом; каждый каталог, созданный с помощью git worktree add, является связанным рабочим деревом. Связанные рабочие деревья ресурсоёмки крайне мало: они хранят лишь небольшой файл .git (не папку), указывающий на общий репозиторий, поэтому занимают почти ничего на диске по сравнению со вторым клоном.
Эта страница рассказывает, когда стоит использовать worktree, как добавлять, просматривать, перемещать и удалять рабочие деревья, какие правила применяет Git и на какие подводные камни следует обратить внимание.
Какую проблему это решает
Представьте, что вы глубоко погружены в работу над feature-веткой, когда поступает срочный отчёт об ошибке. Обычно вам пришлось бы спрятать изменения, переключить ветку, исправить ошибку, переключиться обратно и восстановить изменения — это отвлекает и чревато ошибками. С worktrees вы просто создаёте второй рабочий каталог, переключённый на ветку исправления, устраняете баг там, и ваша работа над фичей остаётся полностью нетронутой. Когда сборка требует двух состояний рядом — например, для сравнения поведения или одновременного запуска двух долгих тестовых наборов — worktrees незаменимы там, где stash уже не поможет.
Добавление рабочего дерева
Укажите git worktree add путь и ветку. Чтобы переключить существующую ветку в соседний каталог:
git worktree add ../hotfix hotfixЭто создаёт ../hotfix с переключённой веткой hotfix:
Preparing worktree (checking out 'hotfix')
HEAD is now at 1a2b3c4 Add login formЧтобы одновременно создать новую ветку, используйте -b. Последний аргумент — это начальная точка, на которой основана новая ветка:
git worktree add -b experiment ../experiment mainТеперь у вас есть два независимых рабочих каталога, обеспеченных одним репозиторием. Если полностью опустить ветку, Git создаст ветку с именем последнего компонента пути:
git worktree add ../docs # creates and checks out a branch named "docs"Чтобы проверить коммит без привязки ветки — удобно для тестирования старого релиза — добавьте его в состоянии detached HEAD:
git worktree add --detach ../v1-check v1.0.0Смотрите Detached HEAD для понимания этого состояния.
Просмотр рабочих деревьев
Посмотреть все рабочие деревья, прикреплённые к репозиторию:
git worktree listВывод показывает каждый путь, коммит, на котором находится дерево, и ветку (или (detached HEAD)):
/home/dev/project 1a2b3c4 [main]
/home/dev/hotfix 9f8e7d6 [hotfix]
/home/dev/v1-check 0011223 (detached HEAD)Добавьте --porcelain для стабильного, удобного для скриптов формата.
Перемещение и удаление рабочих деревьев
Чтобы перенести связанное рабочее дерево, позвольте Git обновить его учёт вместо использования команды оболочки mv:
git worktree move ../hotfix ../urgent-fixКогда оно больше не нужно, удалите его (это удалит его каталог):
git worktree remove ../urgent-fixGit откажется удалять рабочее дерево с незафиксированными изменениями или неотслеживаемыми файлами — так вы не потеряете работу случайно. Если вы уверены, обойдите эту проверку с помощью --force:
git worktree remove --force ../urgent-fixЕсли вы вручную удалили папку рабочего дерева командой rm -rf, репозиторий по-прежнему хранит устаревшую административную запись. Очистите её с помощью:
git worktree pruneБлокировка рабочего дерева
Если рабочее дерево находится на съёмном диске или сетевом ресурсе, заблокируйте его, чтобы prune никогда не удалял его записи, пока диск отключён:
git worktree lock ../usb-backup --reason "external disk"
git worktree unlock ../usb-backupКраткий справочник команд
| Команда | Описание |
|---|---|
git worktree add <path> <branch> | Создать рабочее дерево по пути <path>, переключённое на существующую <branch>. |
git worktree add -b <new> <path> <start> | Создать новую ветку от <start> и переключиться на неё в новом рабочем дереве. |
git worktree add --detach <path> <commit> | Добавить рабочее дерево в состоянии detached HEAD на <commit>. |
git worktree list [--porcelain] | Перечислить все рабочие деревья репозитория. |
git worktree move <from> <to> | Переместить связанное рабочее дерево по новому пути. |
git worktree remove [--force] <path> | Удалить рабочее дерево и его каталог. |
git worktree lock / unlock | Запретить или разрешить автоматическую очистку рабочего дерева. |
git worktree prune | Очистить записи о рабочих деревьях, папки которых были удалены. |
Правила и подводные камни
- Одна ветка — одно рабочее дерево. Ветка может быть переключена только в одном рабочем дереве одновременно. Если попытаться добавить рабочее дерево для ветки, уже переключённой в другом месте, Git откажет с ошибкой
fatal: '<branch>' is already used by worktree at .... Это гарантирует, что два каталога никогда не будут конкурировать за один и тот же указатель ветки. Используйте--detachили новую ветку с-b, если нужен один коммит в двух местах. - Локальные изменения не разделяются. У каждого рабочего дерева есть свои рабочие файлы, индекс и stash. Коммиты, ветки, теги и удалённые репозитории разделяются, так как они хранятся в общем хранилище
.git. - Удаление основного рабочего дерева. Нельзя выполнить
git worktree removeдля исходного (основного) рабочего дерева — только для связанных. - Голые репозитории отлично подходят в качестве хоста для рабочих деревьев: клонируйте с помощью
git clone --bare, затем добавьте каждую рабочую ветку как своё собственное рабочее дерево, сохраняя данные репозитория отдельно от любого переключения.
Связанные команды
- git branch — создание и управление ветками, которые вы переключаете в рабочих деревьях.
- git switch — перемещение между ветками внутри одного рабочего каталога.
- git stash — более старая альтернатива быстрому рабочему дереву для одного каталога.