Skip to content

git worktrees — one filesystem per agent, no collisions

Q15 · Parallelism & automation How do you use git worktrees in agent work?

Max-score answer: “I have a workflow (script/skill/Conductor) that creates a worktree per agent automatically.”

The single-checkout era of AI coding ended sometime in Q1 2026. As soon as you have two agents editing the same repository for more than ten or fifteen minutes at a time, a single working directory stops being viable. Agent A starts a refactor on src/api/checkout.ts. Agent B, kicked off two minutes later in a different terminal, opens the same file with a stale read. Agent B writes its edits. Agent A re-reads the file, sees Agent B’s lines, gets confused, reverts half of them. Both agents commit. Now your working tree contains two incomplete changes glued together by accident, and neither agent can explain what happened.

Worktrees fix the file-collision problem at the filesystem layer instead of trying to coordinate it at the prompt layer. Each worktree is a separate directory on a separate branch, all backed by the same .git object database. From the agent’s point of view it’s just cd ~/work/myrepo-fix-checkout instead of cd ~/work/myrepo. From git’s point of view nothing is duplicated — branches and commits are shared, only the checked-out files differ. From your point of view, you get to spawn four, six, eight parallel agents on the same repo and never have to think about which one is going to clobber the others’ edits.

The downside of the old “git stash; git checkout other-branch; do thing; git checkout back” dance was that it forced serial work even when the underlying tasks were parallel. Worktrees remove that constraint. The downside of having multiple full checkouts on disk was that disk was expensive and node_modules was huge — that downside has been steadily eroded by SSDs and by tools that share dependencies between worktrees. The downside that remains, and that catches almost every team that adopts worktrees, is that the runtime doesn’t get isolated for free: two agents on two worktrees both want to bind to port 3000, both expect Postgres on localhost:5432, both read the same .env. That’s a real problem, and we’ll address it below — but it’s a smaller problem than file collisions, because at least it fails loudly instead of silently corrupting your diff.

In short: worktrees are now load-bearing infrastructure for parallel agent work in 2026, in the same way that virtual environments became load-bearing for Python in the 2010s. You don’t need them for a quick one-off chat; you absolutely need them the moment you go past one agent at a time.

You get full marks on Q15 only when all three of these are true:

  • A worktree gets created automatically for every parallel agent task. When you spin up agent #2, you don’t type git worktree add ../myrepo-feat-X feat-X by hand — a tool, script, or skill does it for you. Conductor, Claude Squad, Cursor’s /worktree, or your own ~/.claude/skills/spawn-worktree-agent all qualify. The point is that the friction is gone.
  • The worktree lifecycle is managed, not abandoned. When the agent finishes (PR merged, branch deleted, task cancelled), the worktree is torn down — either automatically by the same tool, or via a git worktree prune step you run weekly. You don’t have eleven half-dead worktrees from three months ago on your laptop.
  • Per-worktree runtime concerns are at least acknowledged. You know that two agents can’t both bind to port 3000, and you’ve done something about it — .envrc per worktree, port offsets, Docker Compose project name based on directory, or a runtime isolation tool like amux. “I just don’t run dev servers in parallel” counts; “I tried and it broke and I gave up” doesn’t.

Anything less — “I know what worktrees are but I create them by hand once a week” or “I tried Conductor once and it didn’t stick” — is mid-tier on Q15.

Conductor (worktree management for parallel agents)

Section titled “Conductor (worktree management for parallel agents)”

Conductor by Melty Labs is the Mac app that brought worktree-per-agent to a non-CLI audience. It orchestrates parallel Claude Code and Codex agents, each in its own isolated git worktree, and gives you a GUI to track them — what each one is doing, which branch it’s on, what files it changed, whether tests passed. The model is “one task = one agent = one worktree”, and Conductor handles the creation and teardown automatically.

The strength of Conductor is the GUI plus the fact that it understands the task lifecycle, not just the worktree. When the task is done you click a button, the worktree is torn down, the branch is either pushed or discarded, and the slot frees up for the next task. For people who don’t want to live in a terminal, it’s the easiest way to hit max score on Q15.

Claude Squad is the Go-based terminal app version of the same idea — manages multiple AI coding agent instances simultaneously, each in its own worktree. When you spin up a new agent, Claude Squad creates an isolated worktree, switches the new agent into it, and gives you a tmux-style UI to flip between them. It runs cross-platform (macOS, Linux, Windows via WSL) and works with Claude Code, Codex CLI, and other coding agents.

If you’re already a terminal/tmux person, Claude Squad is the lowest-friction adoption path. It’s free, open-source, and the model is the same as Conductor’s: every new agent = a new worktree, and that’s the default, not an opt-in.

Cursor 3 (April 2026) shipped the Agents Window as the central multi-agent interface — it runs agents in parallel across local workspaces, cloud environments, git worktrees, and remote SSH. The /worktree command runs git worktree add to create an isolated working directory on a new branch, then spawns an agent process scoped to that directory. Each agent gets its own filesystem view, so edits don’t collide mid-run. When the agent finishes you review the diff and merge.

For Cursor users this is the path of least resistance: it’s already in the editor, it understands the same indexing and rules you’ve configured for the main checkout, and the worktree creation is two clicks instead of a shell command.

The primitives that all of these tools wrap are simple, and worth knowing even if you never run them by hand:

Terminal window
# Create a new worktree on a new branch
git worktree add ../myrepo-fix-checkout -b fix/checkout-validation
# List all worktrees attached to this repo
git worktree list
# Remove a worktree (when the task is done)
git worktree remove ../myrepo-fix-checkout
# Garbage-collect references to deleted worktree dirs
git worktree prune

A thin wrapper script that pairs git worktree add with the cleanup your project needs is enough to score max on Q15 — you do not have to install a third-party tool if you don’t want one:

~/bin/spawn-agent-worktree
#!/usr/bin/env bash
# usage: spawn-agent-worktree <slug>
set -euo pipefail
slug="$1"
repo_root="$(git rev-parse --show-toplevel)"
repo_name="$(basename "$repo_root")"
parent_dir="$(dirname "$repo_root")"
worktree_dir="$parent_dir/${repo_name}-${slug}"
branch="agent/${slug}"
git worktree add "$worktree_dir" -b "$branch"
# Carry over uncommitted local files agents need but git ignores.
cp "$repo_root/.env" "$worktree_dir/.env" 2>/dev/null || true
cp "$repo_root/.env.local" "$worktree_dir/.env.local" 2>/dev/null || true
# Reinstall deps in the new worktree so agents have a working build.
( cd "$worktree_dir" && [ -f package.json ] && npm install --no-audit --no-fund ) || true
echo "$worktree_dir"

Drop that on $PATH, expose it to Claude Code as a slash command (e.g. ~/.claude/skills/spawn-worktree-agent/SKILL.md), and you have the same effect as Conductor or Claude Squad for the 80% case — at the cost of about thirty lines of shell.

Runtime isolation (the part worktrees don’t solve)

Section titled “Runtime isolation (the part worktrees don’t solve)”

Worktrees solve file collisions. They do not solve port collisions, database collisions, cache collisions, or .env collisions. As soon as you run npm run dev in two worktrees at once and both try to bind localhost:3000, the second one will refuse to start. A worktree workflow that ignores this is incomplete.

The 2026 fix patterns:

  • Port offsets by worktree slug. Hash the worktree directory name to a port offset and write it to a per-worktree .envrc (or .env.local). Agent A gets port 3001, Agent B gets 3007, neither fights.
  • Docker Compose project name = worktree directory name. docker compose -p "$(basename "$PWD")" up keeps each worktree’s containers in a separate namespace, including networks and volumes.
  • A dedicated runtime-isolation tool. Open-source projects like amux exist specifically to layer port and process isolation on top of worktrees so two agents don’t compete for the same localhost. If you’re running 4+ parallel agents that all need dev servers, this stops being optional.

You don’t need a sophisticated solution from day one — even a one-line “port offset based on basename $PWD” inside your dev script is enough to move from “broken” to “works”. But you do need something.

Step-by-step: setting up worktree-per-agent

Section titled “Step-by-step: setting up worktree-per-agent”
  1. Pick where worktrees live on disk. A common pattern: keep all worktrees of myrepo as sibling directories — ~/work/myrepo, ~/work/myrepo-feat-x, ~/work/myrepo-fix-y. Avoid nesting worktrees inside the main checkout; tooling (editor indexers, watchers, deps installers) tends to get confused when node_modules searches walk into another worktree.

  2. Decide on a tool, or write the script. Three reasonable choices: (a) install Conductor if you want a GUI on macOS; (b) install Claude Squad if you live in the terminal; (c) write the ~30-line bash wrapper above. Don’t pick all three — pick one and use it for two weeks before reconsidering.

  3. Wire your .env into the spawn step. Every worktree starts as an empty checkout — git doesn’t track .env, .env.local, .dev.vars, or any other ignored file your app needs to boot. Your spawn script or tool must copy these from the main checkout, or agents will fail on first npm run dev. (Conductor and Claude Squad both have hooks for this; the shell wrapper above does it directly.)

  4. Reinstall dependencies in the new worktree. Each worktree needs its own node_modules (or .venv, or target/) because they’re not shared by default. Bake this into the spawn step so agents land in a worktree that already builds. If install time becomes painful, look at pnpm’s content-addressable store, Yarn PnP, or pip --target patterns that share the underlying packages.

  5. Add per-worktree port/runtime isolation. Even a one-liner is fine: derive a port offset from the worktree directory name and export it as PORT/DATABASE_URL/etc. inside the spawned shell. If you use direnv, drop a .envrc in each worktree that sets the offset; if you use Docker, set COMPOSE_PROJECT_NAME to the basename. Verify two worktrees can run their dev server simultaneously before you call it done.

  6. Expose worktree spawn as a one-keystroke action. In Claude Code, write a skill at ~/.claude/skills/spawn-worktree-agent/SKILL.md that documents how to create a new worktree, copy env files, install deps, and start the agent. In Cursor, use /worktree. In Conductor or Claude Squad, the UI does this for you. The point is: spawning a new isolated agent should take seconds, not minutes.

  7. Define a teardown story. Decide what happens when an agent’s task is done. Reasonable defaults: the PR merges, the spawn tool detects the branch was deleted on the remote and runs git worktree remove, and a weekly git worktree prune cleans up stragglers. If you skip this step you’ll have a graveyard of half-finished worktrees within a month.

  8. Stress-test with three parallel agents. Spin up three on different tasks against the same repo at the same time. Confirm none of them collide on files, ports, or test databases. If they do, fix that first — don’t scale to six until three work.

  • Orphaned worktrees. git worktree add is easy; git worktree remove and git worktree prune are easy to forget. Within a month of casual use you’ll have eight directories on disk that nobody owns, half of them on deleted branches. Either bake teardown into the same tool that spawned them, or schedule a weekly git worktree prune && git worktree list audit.
  • Shared node_modules problems. Symlinking node_modules between worktrees to “save disk” is the most common self-inflicted footgun. Different branches need different dep versions; install scripts assume the directory is theirs to manage; lockfile drift causes phantom bugs. Let each worktree have its own node_modules and rely on the package manager’s content store (pnpm, yarn berry) if disk is genuinely tight.
  • .env not copied. .env files are gitignored, so they don’t appear in a fresh worktree. Every agent’s first action is npm run dev, which fails because DATABASE_URL is missing. The agent then “fixes” the problem by inventing a value, and you don’t notice until something explodes. Always copy .env in the spawn step.
  • Port collisions. Two worktrees, both running npm run dev, both want port 3000. Second one errors out, agent retries, agent edits config to use port 3001 — and now the change leaks into the diff. Solve this once with a port offset and forget about it.
  • Cursor / VSCode indexer eating CPU on every worktree. Each worktree is, to the editor, a separate project; opening eight of them at once will pin the CPU. Either close worktree windows when you’re done, or use the editor’s “limit indexers” / “ignore worktree” settings.
  • Treating worktrees as sufficient. Worktrees are necessary for parallel agent work; they are not sufficient. Test databases, message queues, secrets, mocked external services — anything stateful that lives outside the file tree — still needs its own isolation story.
  • Worktrees on the main branch. A worktree pointed at main (or your default branch) creates ambiguity about which directory is “the real one”. Always create the worktree on a fresh branch (git worktree add ../slug -b agent/slug) so there’s exactly one worktree per branch.
  • You can spawn a new agent on a new worktree in under 30 seconds, without typing a git worktree command by hand.
  • Your spawn workflow copies .env (and any other ignored-but-needed files) into the new worktree automatically.
  • You can name the tool or script that creates worktrees for you (Conductor, Claude Squad, Cursor /worktree, or a bash wrapper you wrote).
  • You have at least one example of running two parallel agents on dev servers without port collisions — port offsets, Docker project names, or a runtime-isolation tool handle it.
  • You have a teardown story: when a task ends, the worktree gets removed within a week, not abandoned forever.
  • git worktree list on a real working repo shows fewer than ~10 entries, all of which you can explain.
  • If asked, you can explain in one sentence why worktrees are necessary but not sufficient for parallel agent isolation (runtime state lives outside the file tree).