Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → git worktree: параллельная работа с ветками

git worktree: несколько веток одновременно без stash-жонглирования

Как работать с несколькими ветками параллельно: git worktree вместо переключений и stash, hotfix посреди фичи, ревью чужих веток, CI-сборки рядом — практика и подводные камни.

Прямой ответ

git worktree позволяет одной репозитории иметь несколько рабочих каталогов, каждый на своей ветке — с общим объектным хранилищем (история одна, место на диске почти не дублируется). Главный сценарий: вы посреди большой фичи с незакоммиченным бардаком, и прилетает hotfix — вместо stash-акробатики и пересборки зависимостей git worktree add ../repo-hotfix main, правка в отдельном каталоге, и ваша фича не тронута. Три правила практики: worktree живут рядом с основным каталогом (../repo-task, а не внутри), одна ветка может быть checkout'нута только в одном worktree (защита от рассинхрона), и у каждого worktree свои зависимости и окружение (node_modules/venv не разделяются — это и цена, и преимущество: сломанный install в одном worktree не трогает остальные). Для ревью чужих веток, долгосрочных параллельных задач и локального CI worktree быстро становится незаменимым.

Механика: команды на каждый день

Создание: git worktree add ../proj-feature feature-branch (существующая ветка) или git worktree add -b newtask ../proj-newtask (новая ветка от HEAD), от конкретного коммита/тега — git worktree add ../proj-v1 v1.0 (сборка старой версии без переключения текущего каталога). Обзор: git worktree list (кто где на какой ветке). Уборка: git worktree remove ../proj-feature (каталог удаляется, если чист) и периодический git worktree prune (чистит записи удалённых вручную каталогов). Внутри worktree — полноценный git: коммиты, пуши, те же remote; общий .git — объектники и refs разделяются, поэтому fetch в одном worktree виден всем (экономия и удобство). Ограничение «ветка занята другим worktree» обходится --detach, но обычно это сигнал, что вы что-то делаете не так (две checkout'нутые копии ветки — источник путаницы).

Сценарий 1: hotfix посреди незакоммиченной работы

Классика, ради которой worktree изобретён: три дня работы над фичей, рабочее дерево в состоянии «полурефакторинг», компиляция сломана на середине — и срочный баг в проде. Старый путь: stash (надежда, что применится обратно), или коммит-WIP с последующим fixup, или клонировать репозиторий заново (минуты и гигабайты). Путь worktree: git worktree add ../proj-fix main — десять секунд, правка бага в чистом каталоге, тесты, коммит, пуш, PR — и git worktree remove; ваша фича лежит нетронутой, stash пуст, контекст не потерян. Для монорепозиториев выигрыш ещё больше: не нужно переустанавливать/пересобирать весь workspace основного дерева (стоимость переключения веток в больших репозиториях — в статье про монорепозитории); окружение hotfix-worktree ставится отдельно и минимально.

Сценарий 2: ревью и чужие ветки

Проверка чужого PR локально традиционно означала checkout его ветки — со своим рабочим деревом в заложниках. С worktree: git worktree add ../review-123 origin/pr-123 (или gh pr checkout 123 в отдельном каталоге), прогон тестов, чтение кода с запуском — в изоляции; после ревью каталог удаляется. Полезно и для сравнения версий вживую: два worktree на двух ветках — два запущенных инстанса приложения рядом (на разных портах), поведение сравнивается глазами, а не по диффу. Отдельный постоянный worktree держат под main — «эталонная копия» для отладки «а в main это работает?» без трогания рабочей ветки.

Сценарий 3: долгосрочные параллельные задачи

Задачи на недели (миграция версии, большой рефакторинг) удобно вести в постоянном worktree с собственным окружением: основной каталог живёт обычной жизнью (мелкие задачи, ревью), а «долгострой» не требует ни stash'ей при каждом переключении, ни риска потерять состояние. Практика: каталог-конвенция (../proj-migration), отдельный venv/node_modules, свой запуск сервисов на других портах (порты — главный конфликт параллельных worktree: два runserver на 8000 не живут), и дисциплина — worktree не превращается в «ещё один основной» с месяцами незакоммиченного (коммиты и пуш — как обычно). Для dotfiles-репозитория worktree — способ держать две конфигурации рядом при переезде на новую машину (перенос окружения).

Подводные камни

Первый — окружения не разделяются автоматически: venv/node_modules/target живут в каждом worktree свои (git их не трогает — они в gitignore); «поставил зависимости в одном, не работает в другом» — ожидаемо, ставьте в каждом (или используйте общие кеши пакетных менеджеров — uv/pnpm store делают это дёшево). Второй — пути и tooling: инструменты, зашивающие абсолютный путь (некоторые lock-файлы, IDE-конфиги), могут капризничать; большинство современных (uv, pnpm, cargo) worktree-дружелюбны. Третий — хуки и конфиги: .git в worktree — файл-ссылка на общий каталог; хуки из core.hooksPath применяются общие (pre-commit-фреймворк работает как обычно), а вот локальные .git/hooks без hooksPath в worktree не подхватываются — аргумент в пользу hooksPath/фреймворков. Четвёртый — забытые worktree: worktree list раз в неделю и prune после ручных удалений каталогов.

Практический сценарий: рабочий день с тремя worktree

Утренняя картина: основной каталог proj/ — фича оплаты (ветка feat/payments, запущен dev-сервер на 8000); ../proj-review/ — PR коллеги, прогнали тесты, оставили комментарии, каталог удалён до обеда; прилетает алерт — git worktree add ../proj-fix main, воспроизвели баг (сервер на 8001 — PORT=8001 в env), фикс, тест, PR, worktree remove — двадцать минут, ни одного stash. К вечеру выясняется, что баг был и в релизной ветке — git worktree add ../proj-release release/1.4, cherry-pick фикса, пуш — релизная ветка не пересекалась с фичей физически. Итог дня: три контекста, ноль переключений веток в основном дереве, dev-сервер фичи не перезапускался ни разу — именно это ощущение «git перестал мешать» и есть практическая ценность worktree.

FAQ

Worktree или второй clone? Clone — полная копия объектного хранилища (гигабайты на больших репо) и отдельный remote-стейт (fetch дважды, ветки расходятся); worktree — общее хранилище, мгновенное создание, единый fetch. Clone оправдан, когда нужна физическая изоляция .git (эксперименты с историей, повреждённые репозитории).

Можно ли два worktree на одной ветке? Штатно нет (git блокирует) — и это правильно: параллельные коммиты в одну ветку из двух мест = путаница. Обход --detach легитимен для «посмотреть состояние», не для работы.

Как worktree дружит с IDE? Каждый worktree открывается как отдельный проект (свой индекс, свои настройки запуска) — VS Code/JetBrains поддерживают без оговорок; общий проект с двумя корнями — на любителя. Порты сервисов разносить обязательно.

Стоит ли держать worktree постоянно? Для долгоживущих параллельных задач и «эталонного main» — да; для задач на день — создавать и удалять (дешевле, чем разгребать залежи каталогов). Ревизия worktree list раз в неделю держит хозяйство чистым.

Источники: git-scm — git-worktree, git-switch, Pro Git — ссылки в шапке.