Несколько рабочих деревьев
git worktree add извлекает второе рабочее дерево из одного репозитория, разделяя единое хранилище объектов .git. Запусти долгую сборку или ревью PR на ветке B, продолжая править ветку A — без stash и без второго клона. Одну ветку нельзя извлечь в двух рабочих деревьях сразу.
Ты глубоко в ветке фичи, когда коллега просит отревьюить его PR, для проверки которого нужна полная сборка. Переключение ветки означает спрятать недоделанную работу, ждать checkout, собирать, а потом всё это разматывать обратно. А что, если бы можно было просто иметь второй checkout того же репозитория, открытый в другой папке — на другой ветке — одновременно? Это ровно git worktree.
К концу этого урока ты сможешь развернуть второе рабочее дерево на другой ветке, понять, почему это дешевле второго клона, и уважать единственное правило, держащее рабочие деревья согласованными.
После этого урока ты сможешь с помощью git worktree add извлечь второе рабочее дерево из того же репозитория, перечислять и удалять рабочие деревья, объяснять, как они разделяют одно хранилище объектов, и сформулировать правило, что одну ветку нельзя извлечь в двух рабочих деревьях одновременно.
git worktree add <path> <branch> создаёт второй рабочий каталог, привязанный к тому же репозиторию. Из своего репозитория ты указываешь новую папку и ветку, которую там извлечь:
git worktree add ../review-pr feature/their-pr
# Preparing worktree (checking out 'feature/their-pr')
cd ../review-pr # полноценный второй checkout, на другой веткеТеперь ../review-pr держит файлы для feature/their-pr, пока твоя исходная папка по-прежнему держит твою ветку, нетронутой. Можно собирать, тестировать или читать в одной, правя в другой — без stash, без танца с ветками.
Все рабочие деревья разделяют одно хранилище объектов .git, и это делает их дешёвыми. Второй git clone копирует всю базу объектов — каждый коммит, дерево и blob — заново. Worktree этого не делает: коммиты, ветки и история живут единожды в основном репозитории, а каждое лишнее рабочее дерево получает лишь свои извлечённые файлы плюс небольшой административный указатель:
git worktree list
# /home/you/project a1b2c3d [feature/search]
# /home/you/review-pr 9f3c1a2 [feature/their-pr]Поскольку хранилище объектов общее, коммит, сделанный в одном рабочем дереве, сразу виден всем остальным — это разные окна в один репозиторий, а не отдельные копии.
Ветку можно извлечь только в одном рабочем дереве за раз. Поскольку все рабочие деревья разделяют ветки, позволить двум из них сидеть на одной ветке означало бы, что два рабочих дерева дерутся за один указатель ветки. Git это запрещает:
git worktree add ../hotfix main
# fatal: 'main' is already checked out at '/home/you/project'Если тебе действительно нужно основать новую работу на main, создай для нового рабочего дерева ветку из него — git worktree add -b hotfix/login ../hotfix main создаёт свежую ветку hotfix/login, начинающуюся на main, и извлекает её там.
Убирай рабочие деревья через remove, а не rm -rf. Когда закончил, правильное удаление рабочего дерева также чистит внутренний учёт git:
git worktree remove ../review-pr # удалить рабочее дерево и его админ-запись
git worktree prune # подчистить записи о деревьях, удалённых рукамиЕсли удалить папку рабочего дерева вручную, git всё ещё считает, что она существует, пока ты не сделаешь prune. Заметь также, что артефакты сборки и неотслеживаемые файлы в рабочем дереве локальны для этой папки, так что долгая сборка в ../review-pr никогда не трогает твою папку с фичей.
▸Почему это работает
Почему предпочесть worktree второму клону? Три причины. Диск и время: не нужно заново скачивать или копировать всю базу объектов — большие репозитории клонируются медленно, а worktree почти мгновенен. Общее состояние: коммиты, подтянутые ссылки и заначки видны между рабочими деревьями, потому что репозиторий один, так что не приходится push-и-pull между двумя клонами, чтобы перенести работу. Один источник истины: единый .git означает отсутствие риска, что два клона тихо разойдутся. Компромисс в том, что они связаны — испорти общее хранилище объектов, и пострадает каждое рабочее дерево.
Ревью PR, не бросая свою работу.
Ты посреди фичи на feature/search с незакоммиченными правками, а коллеге нужно отревьюить его feature/checkout-redesign с настоящей сборкой.
# из папки проекта, всё ещё на feature/search с грязными файлами:
git worktree add ../review feature/checkout-redesign
cd ../review
npm install && npm run build # собрать и протестировать его ветку здесь
# ... оставить комментарии ревью ...
cd ../project # твой грязный feature/search ровно как ты его оставил
git worktree remove ../review # готово — убрать за собойТвои правки feature/search никуда не двигались: ни stash, ни коммита, ни суеты с checkout. Сборка для ревью прошла в отдельной папке против той же общей истории, а git worktree remove убрал за собой, когда ты закончил. Если бы ты попробовал git worktree add ../review feature/search, git отказал бы — эта ветка уже извлечена в project/.
▸Частая ошибка
Повторяющаяся ловушка — попытка извлечь ветку, уже живую в другом рабочем дереве, и недоумение от fatal: '<branch>' is already checked out. Это не баг — это git защищает тебя от двух деревьев, мутирующих одну ветку. Либо работай в новом рабочем дереве на другой ветке, либо создай новую ветку из той, что хотел (-b). Вторая ловушка — удаление папок рабочих деревьев через rm -rf, оставляющее устаревшие записи; всегда используй git worktree remove или выполни git worktree prune, чтобы подчистить потом.
git worktree add <path> <branch> даёт тебе второе рабочее дерево из того же репозитория, так что можно собирать, тестировать или ревьюить на одной ветке, продолжая править другую — без stash, без второго клона. Все рабочие деревья разделяют одно хранилище объектов .git, что делает их дешёвыми и держит коммиты сразу видимыми между ними; цена в том, что они связаны. Твёрдое правило: ветку можно извлечь только в одном рабочем дереве за раз — создай новую ветку (-b), когда нужна работа на основе уже извлечённой ветки. Убирай через git worktree remove (и prune для удалённых руками папок). Дальше ты сделаешь сам git быстрее в управлении с помощью алиасов и конфигурации.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.