Two Agents, Two Worktrees, One Merge
Build two features at the same time, in two folders, with two agents — then put them back together.
run two agents in two worktrees at once, merge both branches, and resolve the conflict that follows
- Your project in git with a clean status and everything pushed (Lab 06)
- Claude Code run at least once in that folder, so the workspace is trusted (Lab 01)
- A CLAUDE.md in the repo (Lab 03)
- Three terminal windows — two to work, one to watch
- A paid Claude plan. Two sessions burn roughly double.
A git worktree is a second folder of the same repository, checked out on its own branch. Two folders means two agents can edit at the same time and never see each other’s files. The merge afterwards is where you find out whether that was a good idea.
Two features in parallel, one deliberate conflict, and an answer to the only question that matters here: was it faster, or just twice as expensive?
Before you open a second terminal, look at the bill
Parallelism is not a speed setting. Anthropic’s January 2026 guidance puts a multi-agent setup at three to ten times the tokens of one agent for the same task, and says to exhaust single-agent options first. The earlier research-system post measured its own stack at about fifteen times the tokens of chat, and noted that most coding work has fewer genuinely parallel parts than research does.
That C compiler is the ceiling: sixteen instances in containers, roughly 2,000 sessions, about 100,000 lines of Rust. It worked because the test suite was near-perfect. Parallel agents without an automated check only multiply code nobody verified.
Anything sequential. Anything where both halves depend on one design decision. Anything a better prompt or a /clear would have fixed. Anything you cannot test automatically.
Two features that touch different files. A build plus a separate review with fresh eyes. Work you can test half at a time, in a browser, before the halves ever meet.
Six things that must be true first
Run both agents, then merge them
Pick two features that do not share a decision
For QAIRU Event Sign-up: a dark mode toggle, and a seats-left counter that disables the form when the event is full. One is presentation, one is logic. Neither needs to know what the other decided.
Write both down as one sentence each first. If you cannot, they are not two tasks — they are one, and you should stay in a single session.
Clear the deck
In the main folder:
git status git log --onelineStatus must be clean. You are about to have three copies of this repo on disk; do not leave yourself guessing which one holds uncommitted work.
Terminal A — start the first agent in its own worktree
claude --worktree dark-modeThat one flag does the whole setup: a new folder at
.claude/worktrees/dark-mode/on a new branch,worktree-dark-mode. You never rungit worktree addyourself. Then give it a scoped prompt:Add a dark mode toggle to the sign-up page. Scope — you may edit ONLY these files: index.html, styles.css Do not touch CLAUDE.md, README.md, or anything under .github/. Requirements: - A visible toggle in the header. - The choice is remembered in localStorage and applied before first paint. - Form labels and the submit button stay readable in both themes. Follow CLAUDE.md. When it works, commit on this branch with a one-line message. Then stop and tell me what you changed, file by file.Terminal B — start the second agent from the same main folder
Open a second terminal window in the same project folder. Do not open it inside the first worktree.
claude --worktree seats-leftAdd a seats-left counter to the sign-up page. Scope — you may edit ONLY these files: index.html, seats.js Do not touch styles.css, CLAUDE.md, or README.md. Requirements: - Show "N seats left" next to the form, read from one capacity constant. - When N reaches 0, disable the submit button and show a short "full" message. - All logic lives in seats.js. index.html gets one script tag and one container div. Follow CLAUDE.md. When it works, commit on this branch with a one-line message. Then stop and tell me what you changed, file by file.Notice what both prompts share: an explicit file list. That is the most useful line in this lab.
Terminal C — watch from outside while they work
git worktree listThree entries: your main checkout and the two worktrees. Open each worktree’s
index.htmlin a browser and test the features separately, now, while the agents still run. This is the part that pays for itself — each half is tested before it meets the other.If your project has dependencies, run your install command inside each worktree. A worktree is a fresh checkout;
node_modulesdoes not travel.Review each branch with a context that did not write it
After agent A commits, in Terminal A:
Use a subagent to review this branch's diff against the main branch. Report only correctness problems and violations of CLAUDE.md — not style, not naming. For each finding give me: the file, what breaks, and the smallest fix. If you find nothing real, say so and stop.A subagent gets its own context window, so it is not attached to code it just wrote; the best-practices page recommends exactly this split. Fix what is real, ignore the rest, repeat in Terminal B.
Exit both sessions and keep the worktrees
Leave each session. A worktree with no changes is removed automatically on exit; one with commits asks whether to keep or remove it. Choose keep — you still need those branches.
Merge the first branch
Back in the main folder:
git merge worktree-dark-modeThis one lands clean: nothing on main has moved since the branch started.
Merge the second branch and meet the conflict
git merge worktree-seats-leftBoth agents edited
index.html. When their edits land in the same region, git stops and leaves conflict markers in the file — the expected outcome here, not a mistake. Hand it to an agent in the main folder:git merge left conflict markers in index.html. Resolve them so BOTH features survive: the dark mode toggle and the seats-left counter. Do not delete either feature to make the conflict go away. When the file is clean, show me the resolved section, then give me the exact steps to test both features in the browser before I commit the merge.Read the resolved section yourself before committing. An agent resolving a conflict is guessing at intent, and the cheapest way to lose a feature is to accept a resolution that quietly dropped half of it.
If git merges both edits without complaining, you got lucky with line numbers. Open the page anyway and check that both features are still there — a clean merge is not a working page.
Verify on main, then clean up
Open the page from the main folder. Both features must work together: toggle the theme, and watch the seats counter still update.
git worktree remove .claude/worktrees/dark-mode git worktree remove .claude/worktrees/seats-left git branch -d worktree-dark-mode worktree-seats-left git worktree listRemove the worktrees before deleting the branches — git refuses to delete a branch that is still checked out somewhere. The last command should show only your main checkout.
Optional finish, from a normal shell:
claude -p "Summarize what changed in the last 3 commits in 5 bullets" \ --allowedTools "Bash(git log *),Bash(git diff *)" --output-format jsonFind
result,session_idandtotal_cost_usdin the JSON. That last field is what this lab is really about. The--allowedToolsline is not decoration:-pstarts in Manual mode, so a command you have not allowed is denied outright, and the summary gets written without ever reading the log.
The conflict was the lesson, not the accident
Worktrees isolate files. They do not isolate decisions. Both agents wrote good code for index.html and still collided, because neither knew the other was rearranging the same header. Claude Code enforces the file half: inside a worktree session it blocks edits, commands and git redirects aimed at the main checkout. Nothing enforces the decision half. You do.
So the real skill is not typing --worktree. It is splitting work along file lines before anything starts:
- One owner per file. Name the files in each prompt, as you did above.
- Give the second agent its own file where you can.
seats.jsexists so that only one line ofindex.htmlhas to change. - Never let two agents edit CLAUDE.md, the README or the config in the same run.
- Merge the same day. Stale branches turn a small conflict into an afternoon.
When two agents is an expensive way to get one result
Cognition’s June 2025 argument against multi-agent systems holds where it matters: actions carry implicit decisions, and conflicting decisions produce bad results. Their example is two subagents building a game — one makes a Mario-style background, the other a bird that does not match it, and the lead agent is left merging two incompatible assumptions. Your index.html conflict, scaled up.
So skip the second agent when the work is sequential, when both halves share a decision, when a sharper prompt or a /clear would have done it, or when you have no automated check. The default that survives real work is modest: one agent, subagents for research, a fresh context to review.
Go deeperWhere the branch actually starts from, and how to bring your .env along
By default worktrees use worktree.baseRef: "fresh" — they branch from the remote default branch (origin/HEAD), falling back to local HEAD when there is no remote. To include unpushed work instead, set {"worktree": {"baseRef": "head"}} in your Claude Code settings.
A fresh checkout also carries no ignored files and no dependencies. List the ignored files you need — .env, for example — in a .worktreeinclude file using gitignore syntax, and they are copied into each new worktree. Dependencies you reinstall. Source: the worktrees docs.
Go deeperThe manual route, which works in any tool
--worktree is Claude Code’s wrapper around plain git, so the same isolation works with Cursor, Codex, Gemini CLI or a bare editor:
git worktree add ../qairu-dark-mode -b dark-mode
git worktree list
git worktree remove ../qairu-dark-modeThen cd into that folder and start whichever agent you like.
Go deeperBigger than two: /batch, agent teams and workflows
/batch followed by one instruction splits a large change across 5–30 worktree-isolated subagents, each opening its own pull request. Agent teams — a lead plus teammates sharing a task list — are experimental and off by default, and the docs say plainly that teammates are not worktree-isolated, so you partition files by hand; the costs page puts them at roughly seven times a standard session’s tokens when teammates run in plan mode. Dynamic workflows run up to 16 concurrent agents by default. Read the agents overview first — all three multiply the bill you just measured.
Pre-flight, the file-ownership rules that prevent most conflicts, the merge and cleanup commands in order, and the questions that send you back to a single session instead.
Both features work together on your main branch, `git worktree list` shows only the main checkout, and you can explain out loud why the two agents never overwrote each other's files.