Claude Code, OpenCode and a human in one repository
In the aredel repository a person, Claude Code and OpenCode work on the same code, often on the same day. This page is about how they share the repository: who writes where, who commits and who merges. How each tool is configured is covered in Building AI agents: OpenCode and Claude Code in one repo.
What goes wrong in one shared checkout
A checkout has one working tree and one index, the staging area. When two agents and a person write into the same checkout, each sees the half-finished work of the others. In aredel this happened within two days:
- Mixed staging, 2026-10-22. An OpenCode session staged whole files, the backoffice main.py, App.jsx and README, while a Claude Code session had unfinished changes in the same files. The index now held both sessions' work, and the staged main.py imported functions that existed only in a file Claude Code had not staged: the snapshot about to be committed failed with an ImportError. Separating the two took manual work on the index.
- A shared generated file, 2026-10-23. One session regenerated sitemap.xml, which picked up a page another session was still writing; later the file was put back to its committed version and a backup next to it disappeared. Nothing in the working tree showed who had done what.
- Hooks act for everyone. A post-commit hook stages the feed files after every commit, so the next git commit, by anyone, includes them. pre-commit stashes all unstaged changes while its checks run, including another agent's work in progress.
None of these is a bug in a tool. They follow from several writers sharing one working tree and one index.
The model: one writer per checkout
- One working tree per writer. Each agent gets its own checkout of the same repository, a git worktree; the person keeps the main one.
- One branch per task. Named after the writer and the task: claude/str-move, opencode/logs.
- One person merges. Agents may commit on their own branch; only the person merges into main and pushes.
- Generated files have one writer. The sitemap and the feed are regenerated on main after a merge, never on an agent branch (below).
A worktree and a branch per agent
A worktree is a second working directory of the same repository, with its own index and its own branch; objects and history are shared, so it costs little disk. From the main checkout, create one per agent, next to it:
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]
The output above is from a test on a throwaway repository named site, 2026-10-23, after each agent had made one commit in its own worktree. The main checkout stayed clean: no file of either agent appeared in it, and each commit landed on its own branch.
Starting each tool in its worktree
Each tool works in the directory it starts in, so start it inside the agent's worktree. Claude Code can also create the worktree itself: claude --worktree name, short -w, starts the session in a new worktree on its own branch, and the same command with another name in a second terminal starts a second isolated session. The repository needs at least one commit; see Claude Code worktrees:
cd ../site-claude && claude
claude --worktree str-move
OpenCode 2.1.3 has no worktree flag on the command line, but it takes the directory to start in as an argument:
opencode ../site-opencode
Inside one session the tools can isolate further: a Claude Code subagent with isolation: worktree runs in a temporary worktree of its own, see Claude Code subagents, and OpenCode 2.x can create worktrees for parallel features, see OpenCode.
What a new worktree does not have
A worktree contains the tracked files and nothing else. Everything git ignores stays in the main checkout:
- Environments: Python .venv folders, node_modules, built UI files. Create them again in the worktree before running tests, for example with uv sync.
- Local data: ignored data folders and databases are missing, which is usually what you want for an agent.
- Config: tracked agent config comes along: AGENTS.md, skills, opencode.jsonc, .claude/settings.json. Deny rules written with a leading * or anchored at the filesystem root keep matching in the new location; see Path patterns that match.
- Running services: the aredel local site runs in a container with a fixed name and port 8080 that serves the src folder of the checkout it was started from. To look at an agent branch in the browser, stop it and start it from that worktree, or merge first.
Review and merge
The person reviews each branch against main with three dots, which shows only what the branch added, then merges it with a merge commit so the branch stays visible in history:
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
When a branch is merged, remove its worktree and the branch:
git worktree remove ../site-claude
git branch -d claude/str-move
Files with one writer
Some files are rebuilt from the whole tree: in aredel the sitemap and the feed. Two branches that both rebuild them always conflict, and a rebuild on a branch misses pages from the other branches. Rebuild them once, on main, after merging; an agent that adds a page only notes that the sitemap needs regenerating. The same goes for any file a hook writes for everyone.
Who commits, who pushes
In aredel an agent never commits without asking, and the deny rules of both tools forbid git push for every agent, see Deny rules for OpenCode and Claude Code. With worktrees that rule stays simple: an agent may commit on its own branch when the person agrees; the person merges into main and is the only one who pushes, to GitHub or to a local server. The rule held even for a throwaway server on 127.0.0.1: in the Forgejo test the push was refused for Claude Code and run by the person.
Pull requests on a local server
Reviewing with git diff works, but a web page with the diff, comments and a merge button is easier when several branches wait at once. A GitHub-like server can run on the same machine in a container; with it the flow becomes: the person pushes an agent branch, opens a pull request, reviews and merges it, then pushes main to GitHub. A tested setup with Forgejo, and the alternatives, are in A local GitHub in a container.
If you must share one checkout
- Give each agent its own area: one agent per folder or task at a time, as the routing table in AGENTS.md does for skills.
- Stage by explicit path or with git add -p, never git add -A, and look at git diff --cached --stat before every commit.
- Before committing, check that the staged snapshot works on its own: the ImportError above passed every check that looked at the working tree.
- Commit one task before the next agent starts in the same files.
Checklist
- One worktree and one branch per agent and task; the person keeps the main checkout.
- Start each tool inside its worktree, or use claude --worktree.
- Recreate ignored environments in a new worktree before running tests.
- Review with git diff main...branch, merge with --no-ff, then remove the worktree.
- Regenerate the sitemap and other tree-wide files only on main, after merging.
- Only the person merges into main and pushes.
Official sources:
Article author: Arthur Isaev