Run parallel Claude Code agents with git worktrees
· by VishwamDhavale
To run multiple Claude Code agents in parallel with git worktrees, give each agent its own worktree on its own branch, start claude in that directory, and merge the branches back when they finish. Each worktree is a separate checkout that shares one repository, so the agents cannot overwrite each other’s files. This post covers the commands, the pitfalls, and one problem worktrees do not solve: a rule that changes while the agents are running.
Why worktrees
Two agents in one checkout edit the same files, switch the same branch and trip over each other’s uncommitted changes. Two full clones avoid that but cost disk and drift apart. A git worktree sits between them. It is a second working directory attached to the same .git, with its own checked-out branch, its own index and its own untracked files.
- One branch per agent, so each agent’s work is a reviewable diff.
- Commits, branches and stashes are shared, so nothing needs fetching between worktrees.
- A mistake in one worktree is deleted with one command and touches nothing else.
Set up one worktree per agent
From the main checkout, create a worktree and a new branch in one step:
git worktree add ../app-auth -b agent/auth git worktree add ../app-billing -b agent/billing git worktree list
-b creates the branch from the commit you are on. git worktree list prints each worktree with its path, its commit and its branch, so you can see at a glance which agent has what. Put the worktrees next to the repo, not inside it, so the main checkout does not see them as untracked files.
Then start an agent in each one, in separate terminals:
cd ../app-auth && claude cd ../app-billing && claude
Each session loads the CLAUDE.md from its own directory. Any agent that reads the working directory works the same way, including Codex and Cursor.
Merge the work back
When an agent is done, review its branch like any other. From the main checkout:
git merge agent/auth git worktree remove ../app-auth git branch -d agent/auth
git worktree remove deletes the directory and its registration. git branch -d deletes the branch only if it is merged, which is the safe default. Conflicts between two agents’ branches show up at merge time, in the normal way. Worktrees prevent agents from clobbering each other while they work. They do not make two agents editing the same function compatible, so give each agent its own area of the code.
Common pitfalls
A branch can only be checked out once
Git refuses to check out one branch in two worktrees. Trying it fails with a message like this, and the same happens from the main checkout:
fatal: 'agent/auth' is already used by worktree at '/path/to/app-auth'
That is a feature. Use one branch per agent. If you need to look at the same commit elsewhere, use a new branch or git worktree add --detach.
Untracked files do not come along
A new worktree is a fresh checkout, so it contains tracked files only. node_modules, .env and any other ignored file are missing. Run your install step in each worktree and copy the env file over. Agents that fail with “module not found” or a missing variable are usually hitting this.
Ports and databases are shared
Worktrees isolate files, not the machine. Two dev servers that both bind port 3000 will collide, and two agents running migrations against one local database will step on each other. Give each worktree its own port and its own database name, for example through its .env.
Cleanup is manual
git worktree remove refuses to delete a worktree with modified or untracked files and tells you to use --force. That is worth respecting, because forcing it throws the agent’s uncommitted work away. If you delete a worktree directory by hand, run git worktree prune to clear the stale registration. Check git worktree list now and then, since abandoned worktrees keep their branches alive.
The problem worktrees create
Because each worktree is its own checkout, each agent reads its own copy of CLAUDE.md, on its own branch. That copy was frozen when you created the branch. If you or a teammate change a rule on main while the agents are running, no running agent is told. The file changed in the repository, and none of their checkouts has it.
Here is the case we tested. Two agents build features in separate worktrees. Halfway through, someone commits “timestamps are epoch ms, not ISO” to main and updates the rules file. Both agents keep writing ISO strings.
All of the following are small samples that we ran ourselves:
- In the demo on the trailstone home page, with CLAUDE.md 0 of 3 agents switched. With trailstone, 3 of 3.
- With a decision reversed mid-work and agents in separate worktrees, trailstone reached 15 of 15 running agents.
- In separate clones, trailstone reached 9 of 9. A teammate’s pushed CLAUDE.md edit reached 0 of 3 clones that had not pulled, against 3 of 3 for trailstone.
There is a correction we owe you. An interactive Claude Code session did notice a CLAUDE.md edit made in its own checkout, 4 of 4 times. So the model does not ignore the file. The gap is narrower: it is any agent whose checkout never sees the change, which means other worktrees and clones that have not pulled. If you run one agent at a time, or every agent shares one checkout, you do not have this problem. For how CLAUDE.md and AGENTS.md relate, see CLAUDE.md vs AGENTS.md.
Also: for rules that never change, a plain CLAUDE.md worked about as well as trailstone and costs less, tested with up to 100 rules. Do not add a tool for rules that hold still.
How trailstone handles it
trailstone is a decision ledger that lives in your repo, in .trailstone/decisions.yml. A decision names the files it governs. Reversing one is a new entry that supersedes the old:
npx trailstone init --goal "ship the billing API"
trailstone decide "Timestamps are ISO strings" \
--why "matches the public API" --scope src/api/
trailstone reverse <id> "Timestamps are epoch ms, not ISO"Claude Code, Codex and Cursor are told before they edit a governed file, wherever that agent is checked out. Any MCP client can ask through trailstone mcp. Agents without hooks read a short block that trailstone writes into AGENTS.md. A pre-push guard and a CI check work with any tool.
What it does not do
- It flags and blocks. It does not fix code. An agent or a person makes the change.
- A flag means “built on”, not “broken”. Any commit to a flagged file clears it.
- It only watches the files a decision names, blocks only on an exact scope match, and does not follow renames.
- It does not create or manage worktrees, install dependencies or merge branches. Everything above is still on you.
- It is not a replacement for CLAUDE.md. The two work together.
There is no server, no account and no telemetry. The one network call is a background git fetch of origin’s default branch, and TRAILSTONE_FETCH=0 turns it off. It needs Node.js 20.17 or later. The README lists exactly what installing it changes.
A checklist
- One worktree and one branch per agent, next to the repo.
- Install dependencies, copy env files and pick a distinct port in each.
- Give each agent its own area of the code.
- Merge, then
git worktree removeandgit branch -d. - If rules can change while agents run, try
npx trailstone demo. It shows the failure and the fix on a throwaway repo in about ten seconds.