Home / Blog / Field notes

Field notes

Git Worktrees for Parallel Agents: The Setup That Actually Holds Up

Running several coding agents at once on one repo sounds great until they stomp each other's files. Here is the worktree layout we run in production, the three failure modes that cost us real time, and the rules that keep it boring.

If you run more than one coding agent against the same repo, you hit the same wall everyone hits: two agents editing the same working tree at the same time corrupt each other's work. One stages a file the other just rewrote. A rebase lands on top of half-written changes. You spend the afternoon untangling a mess that the parallelism was supposed to save you from.

Git worktrees fix the file-collision problem cleanly. Each worktree is a separate working directory backed by the same .git object store, checked out to its own branch. Two agents in two worktrees can both edit, stage, and commit without touching each other's files. This is the layout we run in our own harness, and below is the version that held up after we stopped fighting it.

What a worktree actually is

A normal clone has one working directory tied to one branch at a time. A worktree lets one repository have several working directories at once, each on its own branch, all sharing the same object database and ref store. You create one like this:

git worktree add ../agent-a -b feature/agent-a
git worktree add ../agent-b -b feature/agent-b
git worktree list

Now ../agent-a and ../agent-b are full checkouts. An agent working in each can run its own edits, commits, and builds. They never collide on files because they are literally different directories. When a worktree is done, you remove it:

git worktree remove ../agent-a

The shared object store is the win: no second clone, no duplicated history, and a branch committed in one worktree is immediately visible to the others through the common refs. The cost is that the worktrees are not isolated from the shared .git internals, which is where the sharp edges live.

The layout we run

We keep worktrees under a single predictable directory per repo, one per parallel work area, and we assign exactly one writing agent per worktree. The convention that matters: a worktree is a write area owned by one agent, and no other agent writes inside it.

repo/
  .claude/worktrees/
    backend/      # agent A: backend changes only
    frontend/     # agent B: frontend changes only
    docs/         # agent C: docs only

Single-writer-per-area is the rule that prevents almost every problem. If two agents both need to touch the backend, they do not get two backend worktrees racing the same files. They either serialize through one worktree, or the work gets split along a real seam so the two areas do not overlap. Worktrees solve file collisions between different areas. They do not magically merge two agents editing the same file, and pretending otherwise is how you get conflicts you have to resolve by hand anyway.

Failure mode 1: the path resolves to the wrong tree

The most expensive bug we hit was an agent that resolved repo paths loosely and wrote into a peer's worktree instead of its own. A dispatched task that says "edit the file in the repo" without pinning an absolute path can land its edits in the wrong working directory. The peer then rebases, finds uncommitted files it never created, and stalls.

The fix is unglamorous: pin the absolute path of the target working directory in the task you hand each agent, and never let a worktree write outside its own directory. "Work in /abs/path/repo/.claude/worktrees/backend" beats "work in the backend worktree" every time, because the agent does not have to guess which directory that resolves to.

Failure mode 2: tooling that "helps" by writing to main

Some orchestration layers offer a built-in worktree-isolation flag. We have been bitten by one that accepted the flag, reported isolation, and then quietly wrote to the main checkout anyway. The agent thought it was sandboxed. It was not. Work landed on the wrong branch and we lost time tracing where it went.

If a tool claims to isolate writes for you, verify it before you trust it: have the agent write a sentinel file, then check with git -C <worktree> status that the change shows up in the worktree you expect and nowhere else. If you cannot confirm where writes land, create the worktrees yourself with git worktree add and pass the explicit path. A manual worktree you can see beats an automatic one you have to take on faith.

Failure mode 3: package installs that relink the parent

This one is ecosystem-specific and it surprised us. In a JavaScript monorepo where a worktree's node_modules is symlinked back to the main checkout, running a plain install inside the worktree can relink the main checkout's dependencies into the worktree's store. Delete the worktree afterward and you can break the parent's installed modules, which then shows up as missing-module errors in tools that were working five minutes ago.

Our rule: install dependencies in the main checkout, with a frozen lockfile, and do not run installs inside a worktree at all. The worktree shares the parent's modules; it does not need its own install. If a worktree genuinely needs different dependencies, that is a signal the work should not be sharing an object store in the first place. This is the behavior we have observed in our setup; if your package manager and symlink layout differ, test the delete-the-worktree case before you rely on it, because the failure is silent until something downstream breaks.

The boring rules that make it work

  • One writer per worktree. Two agents on the same area serialize or split; they do not race.
  • Absolute paths in every dispatch. Tell the agent exactly which directory to write in, never "the X worktree."
  • Verify isolation, do not assume it. Confirm with git -C <worktree> status that writes land where you think.
  • Install in main, not in the worktree. At least until you have tested that your toolchain survives the worktree being removed.
  • Clean up when done. git worktree remove and prune stale entries so the next run starts from a clean floor.

None of this is exotic. Worktrees are a stock git feature, and the parallelism they buy is real: independent work areas, shared history, no second clone. The trouble is never the feature. It is the assumptions layered on top of it, the loose path, the trusted-but-unverified isolation flag, the install that reaches back into the parent. Pin the paths, keep one writer per area, verify where writes land, and the setup gets boring in the best way.

That is the bar we hold our own agents to. If a pattern cannot survive several of them running at once without supervision, it is not a pattern yet.

Get the drops.

New patterns, Claude coverage, and field notes as they land, plus first access to the kits.

Email to subscribe