git worktree: как работать в нескольких ветках одновременно
git worktree позволяет подключить к одному репозиторию несколько рабочих директорий, в каждой из которых открыта своя ветка. Команда git worktree add ../hotfix main создаёт папку с веткой main рядом с проектом, при этом история и объекты общие, а клонировать заново ничего не нужно.
Что делает git worktree
git worktree подключает к одному репозиторию несколько рабочих директорий. В основной папке у вас открыта ветка с фичей, а в соседней — main для срочного хотфикса, и обе существуют одновременно. Объекты, коммиты и ветки общие: коммит, сделанный в одной папке, сразу виден из другой без push и fetch.
Без worktree переключение контекста выглядит так: git stash, git switch main, исправление, git switch обратно, git stash pop. Если в проекте долгая сборка или тяжёлый node_modules, каждое переключение ветки ещё и инвалидирует кэши. Второй вариант — клонировать репозиторий заново, но тогда вы получаете две независимые копии истории, которые нужно синхронизировать через удалённый сервер.
Worktree даёт лучшее из обоих подходов: отдельные папки, но одна база .git. Это возможно потому, что ветка в Git — всего лишь указатель на коммит, а не копия файлов, и ничто не мешает разным рабочим копиям смотреть на разные указатели.
Как создать дополнительную рабочую копию
Базовая форма команды: git worktree add <путь> [<ветка>]. Рассмотрим основные варианты.
Открыть существующую ветку
cd ~/projects/shop
git worktree add ../shop-main main
Preparing worktree (checking out 'main')
HEAD is now at 3f2c1ab Обновить README
Рядом с проектом появится папка shop-main с веткой main. Перейдите в неё обычным cd и работайте как в любом репозитории.
Создать новую ветку сразу с рабочей копией
git worktree add -b hotfix/payment-timeout ../shop-hotfix main
Флаг -b создаёт ветку hotfix/payment-timeout от main и открывает её в новой папке. Флаг -B делает то же, но если ветка уже существует, сбрасывает её на указанный коммит — пользуйтесь им осторожно.
Короткая форма
git worktree add ../experiment
Если ветку не указать, Git создаст новую ветку с именем последнего компонента пути (здесь experiment) от текущего HEAD. Если ветка с таким именем уже есть, она и будет открыта.
Рабочая копия без ветки
git worktree add --detach ../shop-v1.4 v1.4.0
Режим detached HEAD удобен, чтобы собрать или проверить старый релиз по тегу, не создавая лишних веток.
Ветка с удалённого сервера
git fetch origin
git worktree add ../review-auth feature/auth
Если локальной ветки feature/auth нет, но есть ровно одна удалённая origin/feature/auth, Git создаст локальную ветку с отслеживанием — как при git switch feature/auth. Так удобно ревьюить чужой pull request, не трогая свою работу.
Как посмотреть и удалить рабочие копии
git worktree list
/home/anna/projects/shop a1b2c3d [feature/cart]
/home/anna/projects/shop-hotfix 7e8f9a0 [hotfix/payment-timeout]
/home/anna/projects/shop-v1.4 5d6e7f8 (detached HEAD)
Первая строка — основная рабочая копия (main worktree), остальные — связанные (linked). Для скриптов есть машиночитаемый вывод git worktree list --porcelain.
Когда хотфикс влит, удалите рабочую копию:
git worktree remove ../shop-hotfix
git branch -d hotfix/payment-timeout
git worktree remove удаляет папку и служебные записи. Если в копии есть незакоммиченные изменения или неотслеживаемые файлы, команда откажется работать; добавьте --force, только если уверены, что они не нужны. Обратите внимание: сама ветка при этом не удаляется, её удаляют отдельно.
Если папку удалили вручную
Удаление папки через файловый менеджер или rm -rf оставляет в .git/worktrees «осиротевшую» запись, и ветка продолжает считаться занятой. Очистите такие записи:
git worktree prune --verbose
Git периодически делает это и сам при сборке мусора, но ждать не обязательно.
Как это устроено внутри
В связанной рабочей копии вместо папки .git лежит файл .git с одной строкой:
gitdir: /home/anna/projects/shop/.git/worktrees/shop-hotfix
В этой служебной папке хранятся данные, уникальные для рабочей копии: свой HEAD, свой индекс (staging area), свои состояния merge и rebase. Всё остальное общее: объекты, ветки, теги, удалённые репозитории, конфигурация и хуки.
| Своё у каждой рабочей копии | Общее для всех |
|---|---|
| HEAD (текущая ветка или коммит) | Объекты и вся история |
| Индекс (git add) | Локальные и удалённые ветки, теги |
| Незавершённый merge, rebase, cherry-pick | Stash (refs/stash общий) |
| Файлы в рабочей директории | .git/config и хуки |
Из таблицы следует неочевидная деталь: git stash list в любой копии покажет одни и те же записи. Это даже удобно — можно спрятать изменения в одной папке и достать в другой.
Главное ограничение: одна ветка — одна рабочая копия
Нельзя открыть одну и ту же ветку в двух рабочих копиях. Если попробовать, Git ответит ошибкой примерно такого вида:
git worktree add ../shop-copy feature/cart
fatal: 'feature/cart' is already used by worktree at '/home/anna/projects/shop'
(в старых версиях Git текст звучит как «is already checked out at»). Ограничение защищает от ситуации, когда коммит в одной папке молча меняет ветку под ногами у другой. Решения: создать новую ветку от того же коммита (-b), открыть копию в режиме --detach или, если очень нужно, использовать --force, понимая последствия.
По той же причине в основной папке не получится выполнить git switch main, пока main открыт в соседней рабочей копии.
Практические сценарии
Срочный хотфикс посреди фичи
git worktree add -b hotfix/null-price ../shop-hotfix main
cd ../shop-hotfix
# исправляем, тестируем
git commit -am "Исправить падение при пустой цене"
git push -u origin hotfix/null-price
cd ../shop
git worktree remove ../shop-hotfix
Ваша незаконченная фича осталась как была, ничего не пришлось прятать в stash, а IDE с открытым проектом даже не заметила переключения.
Ревью pull request с запуском кода
Отдельная копия для ревью позволяет собрать и запустить чужую ветку, прогнать тесты и при этом продолжать свою работу в соседнем окне редактора.
Сравнение поведения двух версий
Две копии с разными тегами можно запустить параллельно на разных портах и сравнить, например, скорость ответа API до и после оптимизации.
Долгие тесты и сборки
Запустите полный прогон тестов в одной копии и продолжайте писать код в другой — сборка не сломается от того, что вы меняете файлы.
Параллельная работа нескольких AI-агентов
Если над задачами работают несколько агентов или процессов, каждому удобно выдать свою рабочую копию на своей ветке: они не мешают друг другу, а результаты сразу попадают в общий репозиторий.
Как организовать папки при постоянной работе с worktree
Если рабочие копии нужны вам каждый день, договоритесь с собой о структуре, иначе соседние каталоги быстро превратятся в свалку. Популярная схема — одна родительская папка проекта, внутри которой bare-репозиторий и по папке на ветку:
git clone --bare git@example.com:team/shop.git ~/projects/shop/.bare
cd ~/projects/shop
echo "gitdir: ./.bare" > .git
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin
git worktree add main
git worktree add -b feature/cart feature-cart main
Строка с remote.origin.fetch нужна потому, что bare-клон по умолчанию не настраивает отслеживание удалённых веток. В результате в ~/projects/shop лежат папки main и feature-cart, каждая со своей веткой, и ни одна из них не «главнее» другой.
Вторая хорошая привычка — называть папку так же, как ветку (заменяя слэш на дефис). Тогда по выводу git worktree list и по пути в терминале всегда понятно, где вы находитесь. И наконец, удаляйте копию сразу после слияния ветки: старые рабочие копии занимают место и держат ветки «занятыми».
Типичные ошибки и подводные камни
- Зависимости и сборка не общие. Каждая копия — отдельная папка, поэтому
node_modules, виртуальное окружение Python,.envи артефакты сборки придётся создать заново. Неотслеживаемые файлы в новую копию не переносятся. - Рабочая копия внутри основной папки. Команда
git worktree add ./hotfixсоздаст папку внутри проекта, и основная копия увидит её как неотслеживаемые файлы. Держите копии рядом (../) или в отдельном каталоге, либо добавьте путь в.gitignore. - Переместили папку вручную. Связь сломается. Перемещайте через
git worktree move ../old ../new, а если уже переместили — выполнитеgit worktree repairв новой папке. - Копия на съёмном диске пропадает. Чтобы prune не удалил запись о копии на отключённом диске, заблокируйте её:
git worktree lock --reason "внешний диск" ../shop-usb. - Подмодули. Поддержка submodules в рабочих копиях ограничена; после создания копии выполните
git submodule update --initи проверьте результат.
Шпаргалка по git worktree
| Задача | Команда |
|---|---|
| Открыть существующую ветку в новой папке | git worktree add ../dir branch |
| Создать ветку и копию | git worktree add -b new-branch ../dir main |
| Копия без ветки (тег, коммит) | git worktree add --detach ../dir v1.0 |
| Список копий | git worktree list |
| Удалить копию | git worktree remove ../dir |
| Убрать записи об удалённых папках | git worktree prune |
| Переместить копию | git worktree move ../dir ../new-dir |
| Починить связи после переноса | git worktree repair |
| Защитить от prune | git worktree lock ../dir |
git worktree, stash или второй клон
| Критерий | stash | worktree | второй clone |
|---|---|---|---|
| Скорость переключения | Быстро, но с переключением ветки | Мгновенно — просто другая папка | Мгновенно |
| Место на диске | Минимум | Только рабочие файлы | Полная копия истории |
| Синхронизация | Не нужна | Не нужна, история общая | Через push/fetch |
| Одновременная работа | Нет | Да | Да |
Stash остаётся лучшим выбором для коротких отвлечений на пару минут. Для всего, что дольше, или когда нужно держать открытыми две версии, удобнее worktree.
Итог
git worktree — простой способ работать с несколькими ветками одновременно: add создаёт папку, list показывает их, remove и prune убирают. История общая, а HEAD, индекс и файлы у каждой копии свои; одна ветка не может быть открыта в двух копиях. Как устроены ветки и почему переключение между ними такое лёгкое, мы подробно разбираем на практике в курсе по Git.
Частые вопросы
С какой версии Git есть git worktree?
Команда появилась в Git 2.5 и с тех пор заметно доработана, например remove и move добавлены позже. В любой современной версии Git все описанные команды доступны.
Можно ли сделать коммит в одной рабочей копии и увидеть его в другой?
Да, история общая. Коммит сразу виден через git log в любой копии, а слить его можно командой git merge без push и fetch.
Видит ли IDE несколько рабочих копий?
Для IDE каждая копия — обычная папка с проектом, её открывают в отдельном окне. Многие редакторы также показывают список рабочих копий во встроенном интерфейсе Git.
Удаляет ли git worktree remove ветку?
Нет, удаляется только папка и служебная запись. Ветку удаляйте отдельно через git branch -d.
Работает ли git worktree с bare-репозиторием?
Да, популярная схема — держать bare-клон и создавать от него рабочие копии для каждой ветки, тогда «основной» папки с файлами нет вовсе.
Эта тема подробно разобрана с практикой в курсе «Git с нуля до уверенного разработчика».
Перейти к курсу