Claude Code, OpenCode и человек в одном репозитории
В репозитории aredel человек, Claude Code и OpenCode работают с одним и тем же кодом, часто в один день. Эта страница о том, как они делят репозиторий: кто где пишет, кто коммитит и кто сливает. Как настраивается каждый инструмент, описано в «Создание ИИ-агентов: OpenCode и Claude Code в одном репозитории».
Что ломается в одном общем checkout
У checkout одно рабочее дерево и один индекс, то есть область подготовки. Когда два агента и человек пишут в один checkout, каждый видит недоделанную работу остальных. В aredel это случилось за два дня:
- Смешанная подготовка, 2026-10-22. Сессия OpenCode добавила в индекс целые файлы — main.py из backoffice, App.jsx и README, — а у сессии Claude Code в тех же файлах были незаконченные правки. Теперь индекс держал работу обеих сессий, и подготовленный main.py импортировал функции, которые существовали только в файле, не добавленном Claude Code: снимок, готовый к коммиту, падал с ImportError. Разделить две сессии удалось только ручной работой с индексом.
- Общий сгенерированный файл, 2026-10-23. Одна сессия пересобрала sitemap.xml, и в него попала страница, которую другая сессия ещё писала; позже файл вернули к закоммиченной версии, а резервная копия рядом исчезла. Ничто в рабочем дереве не показывало, кто что сделал.
- Хуки действуют за всех. Хук post-commit добавляет в индекс файлы ленты после каждого коммита, поэтому следующий git commit любого автора включает их. pre-commit на время своих проверок прячет все неподготовленные изменения, включая работу другого агента.
Ни одно из этого не баг инструмента. Всё следует из того, что несколько писателей делят одно рабочее дерево и один индекс.
Модель: один писатель на checkout
- Одно рабочее дерево на писателя. Каждый агент получает свой checkout того же репозитория, git worktree; основной остаётся у человека.
- Одна ветка на задачу. Названная по писателю и задаче: claude/str-move, opencode/logs.
- Один человек сливает. Агенты могут коммитить в свою ветку; только человек сливает в main и пушит.
- У сгенерированных файлов один писатель. Sitemap и лента пересобираются на main после слияния, никогда в ветке агента (ниже).
Worktree и ветка на каждого агента
Worktree — это второй рабочий каталог того же репозитория со своим индексом и своей веткой; объекты и история общие, поэтому диск почти не тратится. Из основного checkout создайте по одному на агента, рядом с ним:
git worktree add ../site-claude -b claude/str-move
git worktree add ../site-opencode -b opencode/logs
git worktree list
…/site def75f4 [main] …/site-claude b3ca3b8 [claude/str-move] …/site-opencode 9594175 [opencode/logs]
Вывод выше — из теста на одноразовом репозитории site 2026-10-23, после того как каждый агент сделал по одному коммиту в своём worktree. Основной checkout остался чистым: ни один файл ни одного агента в нём не появился, и каждый коммит попал в свою ветку.
Запуск каждого инструмента в его worktree
Каждый инструмент работает в том каталоге, где запущен, поэтому запускайте его внутри worktree агента. Claude Code умеет создавать worktree сам: claude --worktree name, коротко -w, открывает сессию в новом worktree на собственной ветке, и та же команда с другим именем во втором терминале открывает вторую изолированную сессию. В репозитории должен быть хотя бы один коммит; см. Claude Code worktrees:
cd ../site-claude && claude
claude --worktree str-move
У OpenCode 2.1.3 нет флага worktree в командной строке, но он принимает каталог для запуска аргументом:
opencode ../site-opencode
Внутри одной сессии инструменты умеют изолироваться дальше: субагент Claude Code с isolation: worktree работает в собственном временном worktree, см. Субагенты Claude Code, а OpenCode 2.x может создавать worktree для параллельных фич, см. OpenCode.
Чего нет в новом worktree
Worktree содержит отслеживаемые файлы и ничего больше. Всё, что git игнорирует, остаётся в основном checkout:
- Окружения: папки Python .venv, node_modules, собранные файлы интерфейса. Создайте их заново в worktree перед запуском тестов, например через uv sync.
- Локальные данные: игнорируемые папки данных и базы отсутствуют, и для агента это обычно то, что нужно.
- Конфигурация: отслеживаемый конфиг агентов переезжает вместе с репозиторием: AGENTS.md, навыки, opencode.jsonc, .claude/settings.json. Правила запретов, записанные с ведущей * или привязанные к корню файловой системы, продолжают совпадать и на новом месте; см. Шаблоны путей, которые совпадают.
- Работающие сервисы: локальный сайт aredel работает в контейнере с фиксированным именем и портом 8080 и отдаёт папку src того checkout, из которого запущен. Чтобы посмотреть ветку агента в браузере, остановите его и запустите из этого worktree или сначала слейте ветку.
Ревью и слияние
Человек смотрит каждую ветку относительно main с тремя точками, что показывает только добавленное веткой, и сливает её коммитом слияния, чтобы ветка осталась видна в истории:
git diff --stat main...claude/str-move
str.md | 1 + 1 file changed, 1 insertion(+)
git merge --no-ff claude/str-move
git merge --no-ff opencode/logs
git log --oneline --graph
* 3127cda Merges opencode/logs |\ | * 9594175 Moves the logs * | 47b1b7d Merges claude/str-move |\ \ | |/ |/| | * b3ca3b8 Moves the str section |/ * def75f4 Initial commit
Когда ветка слита, удалите её worktree и саму ветку:
git worktree remove ../site-claude
git branch -d claude/str-move
Файлы с одним писателем
Некоторые файлы пересобираются из всего дерева: в aredel это sitemap и лента. Две ветки, которые их пересобирают, конфликтуют всегда, а сборка в ветке теряет страницы из других веток. Собирайте их один раз, на main, после слияния; агент, добавивший страницу, лишь отмечает, что sitemap нужно пересобрать. То же касается любого файла, который хук пишет за всех.
Кто коммитит, кто пушит
В aredel агент никогда не коммитит без спроса, а правила запретов обоих инструментов запрещают git push любому агенту, см. Правила запретов для OpenCode и Claude Code. С worktree это правило остаётся простым: агент может коммитить в свою ветку, когда человек согласен; человек сливает в main и единственный пушит — на GitHub или на локальный сервер. Правило сработало даже для одноразового сервера на 127.0.0.1: в тесте с Forgejo push был отклонён для Claude Code и выполнен человеком.
Pull request на локальном сервере
Ревью через git diff работает, но веб-страница с diff, комментариями и кнопкой слияния удобнее, когда сразу ждут несколько веток. Сервер в духе GitHub можно поднять на той же машине в контейнере; с ним процесс становится таким: человек пушит ветку агента, открывает pull request, смотрит и сливает его, затем пушит main на GitHub. Проверенная настройка с Forgejo и альтернативы — в «Локальный GitHub в контейнере».
Если один checkout всё же нужен
- Дайте каждому агенту свою область: один агент на папку или задачу одновременно, как таблица маршрутизации в AGENTS.md делает для навыков.
- Добавляйте в индекс по явному пути или через git add -p, никогда git add -A, и смотрите git diff --cached --stat перед каждым коммитом.
- Перед коммитом проверьте, что подготовленный снимок работает сам по себе: ImportError выше прошёл все проверки, которые смотрели на рабочее дерево.
- Закоммитьте одну задачу до того, как следующий агент начнёт в тех же файлах.
Чек-лист
- Один worktree и одна ветка на агента и задачу; основной checkout остаётся у человека.
- Запускайте каждый инструмент внутри его worktree или используйте claude --worktree.
- Пересоздайте игнорируемые окружения в новом worktree перед запуском тестов.
- Смотрите git diff main...branch, сливайте с --no-ff, затем удаляйте worktree.
- Пересобирайте sitemap и другие файлы, собранные из всего дерева, только на main, после слияния.
- Только человек сливает в main и пушит.
Официальные источники:
Автор статьи: Клавдия Кондакова