> · 6 мин

Три Claude Code на одном репо — параллельная разработка через git worktrees без единого конфликта

Три Claude Code на одном репо — параллельная разработка через git worktrees без единого конфликта

Три Claude Code на одном репо — параллельная разработка через git worktrees без единого конфликта

Знакомая ситуация: Claude Code пилит фичу авторизации, а тебе надо срочно пофиксить баг в навбаре. Переключаешь ветку — и Claude теряет весь контекст. Или хуже: два инстанса Claude работают в одной директории и затирают друг другу файлы.

21 февраля 2026 года Anthropic встроили поддержку git worktrees прямо в CLI. Один флаг -w — и у каждого Claude своя песочница.

TL;DR: Флаг claude -w <name> создаёт изолированный worktree с отдельной веткой. Три терминала, три worktree, три задачи — параллельно, без конфликтов. Субагенты тоже умеют: isolation: worktree в frontmatter. Docker-контейнеры разруливаются через port ranges и COMPOSE_PROJECT_NAME. После работы — стандартный мерж через PR.

Проблема: один Claude — одна директория

Claude Code работает в рабочей директории проекта. Пока он рефакторит auth.ts, ты не можешь в той же папке запустить второй инстанс на фикс navbar.tsx — они начнут редактировать одни и те же файлы, ломать git status друг другу и создавать хаос в staging area.

Раньше были обходные пути:

  • Клонировать репо второй раз (дублирует .git, жрёт место)
  • Переключать ветки вручную (Claude теряет контекст)
  • Ждать, пока первая задача закончится (убивает параллелизм)

Git worktrees: одно репо, много директорий

Git worktree — это штатная фича Git (не Claude Code). Она создаёт отдельную рабочую директорию с собственной веткой, но при этом все worktrees разделяют одну базу .git. Никакого дублирования истории, никаких лишних гигабайтов.

# Классический git worktree (работало и раньше)
git worktree add ../my-project-feature-auth -b feature-auth
cd ../my-project-feature-auth

Но Claude Code теперь делает это проще.

Флаг -w: worktree одной командой

# Создать worktree и запустить Claude в нём
claude -w feature-auth

Что происходит:

  • Создаётся директория .claude/worktrees/feature-auth/
  • Из текущей ветки отбранчивается worktree-feature-auth
  • Claude стартует уже внутри этого worktree

Без имени — Claude придумает сам:

claude -w
# Создаст что-то вроде .claude/worktrees/bright-running-fox/

Три терминала — три задачи

Вот как выглядит реальный параллельный workflow:

Терминал 1:

claude -w feature-auth
> реализуй OAuth2 авторизацию через Google

Терминал 2:

claude -w fix-navbar
> пофикси баг: навбар не скрывается на мобильных

Терминал 3:

claude -w refactor-api
> вынеси валидацию из контроллеров в отдельный middleware

Каждый Claude работает в своей директории, на своей ветке. Они не видят изменения друг друга, пока ты сам не сделаешь мерж.

Субагенты тоже умеют

Внутри одной сессии Claude Code может запускать субагентов — и им тоже можно дать изолированные worktrees. Два способа:

Через промпт:

> используй worktrees для своих агентов

Через frontmatter кастомного субагента:

# .claude/agents/parallel-refactor.md
---
isolation: worktree
tools:
  - Read
  - Edit
  - Bash
---
Рефакторь код по описанию. Работай в изолированном worktree.

Каждый субагент получает собственный worktree. Если субагент ничего не изменил — worktree удаляется автоматически. Если есть изменения — они остаются в ветке.

Что происходит при выходе

Когда ты выходишь из сессии worktree, Claude спрашивает:

  • Нет изменений → worktree и ветка удаляются автоматически
  • Есть коммиты или незакоммиченные изменения → Claude предлагает: сохранить (worktree остаётся на месте) или удалить (всё пропадёт)

Вернуться в сохранённый worktree:

cd .claude/worktrees/feature-auth
claude

Мерж результатов

Когда задача выполнена, мерж работает как обычный git:

# Из основной ветки
git merge worktree-feature-auth

# Или через PR (рекомендую)
cd .claude/worktrees/feature-auth
git push -u origin worktree-feature-auth
gh pr create --title "feat: OAuth2 авторизация"

Если ветки трогали разные файлы — мерж пройдёт чисто. Если пересекались — стандартное разрешение конфликтов.

Docker и несколько worktrees: как не сломать тесты

Git worktrees изолируют файлы. Но Docker-контейнеры делят один хост — и тут начинаются проблемы. Три worktree поднимают три docker compose up, все хотят порт 5432 для Postgres и 3000 для приложения. Результат — конфликт портов и ничего не работает.

Есть три стратегии, от простой к продвинутой.

Стратегия 1: Общая база, разные порты приложения

Самый частый случай — база данных одна, приложение в каждом worktree своё. Postgres и Redis шарятся, а порт приложения зависит от worktree.

Добавь в docker-compose.yml переменную для порта:

services:
  app:
    ports:
      - "${APP_PORT:-3000}:3000"
  postgres:
    ports:
      - "5432:5432"

В каждом worktree создай .env с уникальным портом:

# .claude/worktrees/feature-auth/.env
APP_PORT=3001

# .claude/worktrees/fix-navbar/.env
APP_PORT=3002

И обязательно — уникальное имя проекта, чтобы контейнеры не конфликтовали:

# В .env каждого worktree
COMPOSE_PROJECT_NAME=myapp-feature-auth

Без COMPOSE_PROJECT_NAME Docker Compose создаст контейнеры с одинаковыми именами — и второй docker compose up убьёт первый.

Стратегия 2: Полная изоляция с отдельными базами

Если задачи трогают миграции базы данных — шаренный Postgres опасен. Одна миграция в worktree feature-auth может сломать схему для fix-navbar.

Решение — отдельная база на каждый worktree:

services:
  app:
    ports:
      - "${APP_PORT:-3000}:3000"
    environment:
      - DATABASE_URL=postgres://dev:dev@postgres:5432/${DB_NAME:-myapp_dev}
  postgres:
    ports:
      - "${DB_PORT:-5432}:5432"
    environment:
      - POSTGRES_DB=${DB_NAME:-myapp_dev}
# .claude/worktrees/feature-auth/.env
APP_PORT=3001
DB_PORT=5433
DB_NAME=myapp_feature_auth
COMPOSE_PROJECT_NAME=myapp-feature-auth

Да, больше ресурсов. Но каждый Claude может запускать миграции, сидить базу тестовыми данными и ничего не бояться.

Стратегия 3: Port ranges в docker-compose

Для проектов, где worktrees создаются и удаляются часто, можно заранее зарезервировать диапазон портов:

services:
  app:
    ports:
      - "3000-3009:3000"
  vite:
    ports:
      - "5173-5182:5173"

Основной проект на стандартных портах (3000, 5173), каждый worktree получает следующий свободный порт из диапазона. Это поддерживает до 10 одновременных worktrees.

Автоматизация: скрипт для setup

Вместо того чтобы руками создавать .env в каждом worktree, напиши скрипт:

#!/bin/bash
# scripts/setup-worktree.sh
WORKTREE_NAME=$1
PORT_OFFSET=$2

mkdir -p .claude/worktrees/$WORKTREE_NAME

cat > .claude/worktrees/$WORKTREE_NAME/.env << EOF
APP_PORT=$((3000 + PORT_OFFSET))
DB_PORT=$((5432 + PORT_OFFSET))
DB_NAME=myapp_${WORKTREE_NAME//-/_}
COMPOSE_PROJECT_NAME=myapp-$WORKTREE_NAME
EOF

echo "Worktree $WORKTREE_NAME: app on port $((3000 + PORT_OFFSET))"
./scripts/setup-worktree.sh feature-auth 1
./scripts/setup-worktree.sh fix-navbar 2

А если хочется автоматизации на уровне тулзы — Portree делает именно это: автоматический port allocation через хэширование имени ветки, subdomain routing вроде feature-auth.localhost:3000 и TUI-дашборд для мониторинга. Ставится через brew install fairy-pitta/tap/portree.

Тесты: на что обратить внимание

Тесты — отдельная боль. Если тестовый фреймворк поднимает свою базу через Docker, каждый worktree попытается создать myapp_test на том же порту.

Решение — уникальное имя тестовой базы:

# В тестовом окружении
DATABASE_URL=postgres://dev:dev@localhost:${DB_PORT}/myapp_test_${WORKTREE_NAME}

Или используй testcontainers — он сам поднимает контейнер на случайном порту и убирает после тестов. Claude Code в worktree запускает npm test, testcontainers создаёт эфемерный Postgres — никаких конфликтов.

Тулзы для тех, кто хочет больше

Голый -w покрывает базовые потребности. Но если ты регулярно запускаешь 5-10 параллельных задач, есть инструменты:

Parallel Code — десктоп-приложение с единым интерфейсом для нескольких AI-агентов (Claude Code, Codex, Gemini). Каждый получает свой worktree автоматически. Есть мониторинг через QR-код с телефона. Клавиатурная навигация между агентами.

Crystal — похожая идея: запускаешь несколько сессий Claude Code или Codex, каждая в своём worktree. Визуальный diff, тесты, squash коммитов перед мержем в main.

Portree — менеджер серверов для worktrees. Автоматический port allocation, subdomain routing, TUI-дашборд. Ставится через brew install fairy-pitta/tap/portree.

Готчас и подводные камни

Зависимости. Каждый worktree — это отдельная директория. Если у тебя Node.js проект, придётся запустить npm install в каждом worktree. То же с Python venv, Go modules и прочим.

.gitignore. Добавь .claude/worktrees/ в .gitignore, чтобы содержимое worktrees не засоряло git status основного репо.

echo '.claude/worktrees/' >> .gitignore

Rate limits. Три параллельных Claude = тройная нагрузка на API. На бесплатном тарифе быстро упрёшься в лимиты. На Pro — нормально, но следи за потреблением.

Контекст не шарится. Каждый Claude в worktree — это отдельная сессия с чистым контекстом. Если один Claude нашёл баг и пофиксил — второй об этом не знает. Это фича, не баг.

Кому это важно

  • Разработчику — запускай claude -w feature-name и работай над несколькими задачами одновременно, не теряя контекст и не ожидая завершения предыдущей задачи. Docker разруливается через COMPOSE_PROJECT_NAME и уникальные порты
  • Тимлиду — три параллельных Claude на одном проекте = грубо x3 скорость доставки фич. Команда incident.io сократила генерацию API на 18% одним только параллелизмом
  • Следишь за рынком — параллельные AI-агенты в изолированных окружениях становятся стандартом. Crystal, Parallel Code, встроенные worktrees — всё движется к тому, что один разработчик управляет флотом из 5-10 агентов

Как попробовать

  1. Обнови Claude Code до последней версии: claude update
  2. Перейди в свой проект: cd ~/projects/my-app
  3. Добавь .claude/worktrees/ в .gitignore
  4. Запусти первый worktree: claude -w my-feature
  5. Открой второй терминал, запусти второй: claude -w my-fix
  6. Для Docker-проектов: задай COMPOSE_PROJECT_NAME и уникальные порты в .env каждого worktree

Полная документация по worktrees — в официальных docs.

$ ls ./related/

Похожие статьи

subscribe.sh

$ cat /dev/blog/updates

> Свежие заметки о программировании,

> DevOps и AI — прямо в мессенджер

./subscribe