Skip to main content
Module 2: Multi-Agent 6 / 6
Intermediate Session 12 Worktree Isolation Git

Worktree Isolation

Use git worktree per task for complete code isolation with event streams.

March 20, 2026 15 min read

What You’ll Learn

When two agents edit the same file at the same time, one of them loses. Their changes get overwritten, or both sets merge into an incoherent mess. Worktree isolation eliminates this by giving each agent its own complete working directory.

By the end, you’ll understand:

  • Why shared working directories break multi-agent workflows
  • How git worktree provides per-agent isolation
  • The worktree lifecycle: create, work, merge or discard
  • Event streams for monitoring worktree activity
  • Automatic cleanup of unused worktrees

The Problem

Two agents working in parallel on the same repository:

AGENT A: Adding authentication       AGENT B: Adding logging
  Creates src/middleware/auth.ts        Creates src/middleware/logger.ts
  Modifies src/app.ts ←──── CONFLICT ────→ Modifies src/app.ts
  Modifies src/routes/index.ts          Modifies src/config.ts

Both modify src/app.ts. Without isolation, three outcomes are possible:

1. LAST WRITE WINS
   Agent A writes app.ts with auth import
   Agent B writes app.ts with logger import → auth import lost

2. READ-BEFORE-WRITE RACE
   Both read the same version of app.ts
   Both write based on that version → second write overwrites the first

3. MERGE CONFLICT
   Both stage changes → git conflict markers → manual resolution needed

None are acceptable. The root cause: multiple agents sharing a single working directory.

How It Works

Git Worktree: One Repo, Multiple Directories

Git worktree creates additional working directories from the same repository. Each has its own branch and files, but they share git history.

MAIN REPOSITORY                  WORKTREE: AGENT A
/project/                        /project/.worktrees/agent-a/
  ├── .git/  ◀── shared ──▶       (branch: feat/auth)
  ├── src/                         ├── src/        ← independent copy
  ├── tests/                       ├── tests/
  └── package.json                 └── package.json

                                 WORKTREE: AGENT B
                                 /project/.worktrees/agent-b/
                                   (branch: feat/logging)
                                   ├── src/        ← independent copy
                                   ├── tests/
                                   └── package.json

Agent A and Agent B can both modify src/app.ts — they each have their own copy on their own branch.

Spawning Agents with Worktree Isolation

When the parent spawns a child with isolation, the sequence is:

Parent Agent

    ├──▶ 1. CREATE   git worktree add .worktrees/task-42 -b task-42
    │                 → new directory + branch created (fast, uses hardlinks)

    ├──▶ 2. SET CWD  Child agent works in .worktrees/task-42/
    │                 Agent sees a normal project — doesn't know it's a worktree

    ├──▶ 3. WORK     Child reads, writes, tests — all local to worktree
    │                 No impact on main directory or other worktrees

    ├──▶ 4. COMPLETE  Child commits to branch task-42
    │                  Returns: { worktree_path, branch, files_changed }

    └──▶ 5. DECIDE    Parent merges branch → or discards worktree

The child agent needs no special awareness. From its perspective, it works in a normal directory. Isolation is invisible to the worker.

The Full Lifecycle

┌─────────────────────────────────────────────────────┐
│  CREATE                                              │
│    git worktree add <path> -b <branch>               │
│    Fast: hardlinks, not full copy                    │
│                      │                               │
│                      ▼                               │
│  WORK                                                │
│    Agent operates in worktree directory               │
│    All reads/writes isolated. Can run tests locally. │
│                      │                               │
│                      ▼                               │
│  EVALUATE                                            │
│    git diff --stat → changes exist?                  │
│               ┌──────┴──────┐                        │
│               ▼             ▼                        │
│  MERGE                  DISCARD                      │
│    Merge branch         Remove worktree              │
│    into main            Delete branch                │
│               └──────┬──────┘                        │
│                      ▼                               │
│  CLEANUP                                             │
│    git worktree prune                                │
│    Remove directory, clean git references            │
└─────────────────────────────────────────────────────┘

Event Streams: Monitoring Activity

The parent monitors worktree activity through events, without breaking isolation:

Parent Agent (orchestrator)

    ├── AGENT A (worktree: feat/auth)
    │     ├── event: file_created  src/middleware/auth.ts
    │     ├── event: file_modified src/app.ts
    │     ├── event: test_run      3 passed, 0 failed
    │     └── event: task_complete files_changed: 3

    ├── AGENT B (worktree: feat/logging)
    │     ├── event: file_created  src/middleware/logger.ts
    │     ├── event: file_modified src/app.ts
    │     └── event: task_complete files_changed: 3

    └── MERGE DECISION
          Both modified src/app.ts on different branches.
          Git merge handles it if changes are on different lines.
          If conflict: parent resolves with full context of both tasks.

Events flow child-to-parent only. The parent observes without interfering — modifying a worktree while the child works would break consistency.

Automatic Cleanup

Worktrees with no changes are cleaned up automatically:

1. Worktree created for exploration task
2. Agent reads 20 files, concludes "no changes needed"
3. git diff --stat → empty
4. Automatic: git worktree remove + git branch -d
5. No branch, no directory, no mess

This prevents worktree accumulation over long sessions with many parallel agents.

Key Insight

Worktree isolation is what makes true parallel development possible. It is the same concept as feature branches, but applied at the agent level.

The deeper insight: worktrees change the coordination model. Without isolation, agents must coordinate in real-time (“don’t touch app.ts, I’m editing it”). With isolation, agents work freely and conflicts resolve once at merge time. This is optimistic concurrency instead of pessimistic locking — it scales better because agents never block each other.

Hands-On Example

Two agents implementing features in parallel, then merging:

STEP 1: Create worktrees
──────────────────────────────────
git worktree add .worktrees/auth -b feat/auth
git worktree add .worktrees/logging -b feat/logging

STEP 2: Agents work in parallel
──────────────────────────────────
Agent A (in .worktrees/auth/):
  Creates src/middleware/auth.ts
  Modifies src/app.ts:
    + import { authMiddleware } from './middleware/auth'
    + app.use(authMiddleware)
  Runs tests → pass
  Commits: "feat: add authentication middleware"

Agent B (in .worktrees/logging/):          ← simultaneous
  Creates src/middleware/logger.ts
  Modifies src/app.ts:
    + import { logger } from './middleware/logger'
    + app.use(logger)
  Runs tests → pass
  Commits: "feat: add request logging"

STEP 3: Merge results
──────────────────────────────────
git checkout main
git merge feat/auth      → clean merge
git merge feat/logging   → auto-merge (different lines of app.ts)
Final app.ts has BOTH imports. No manual conflict resolution.

STEP 4: Cleanup
──────────────────────────────────
git worktree remove .worktrees/auth
git worktree remove .worktrees/logging

Handling Merge Conflicts

When changes overlap, the parent agent resolves with context:

Agent A adds line 15: app.use(authMiddleware)
Agent B adds line 15: app.use(logger)

Parent reads conflict → understands both intents → resolves:
  app.use(logger)          ← logger first (every request)
  app.use(authMiddleware)  ← auth second (validates credentials)

Isolation Strategy Comparison

No Isolation:   instant setup, zero safety → single agent only
Worktree:       fast setup (hardlinks), full file isolation → parallel agents
Full Clone:     slow (copies repo), full isolation → untrusted agents
Container:      slowest (OS-level), maximum isolation → untrusted code

Worktree hits the sweet spot: strong isolation with minimal overhead.

What Changed

Shared Working DirectoryWorktree Isolation
Agents overwrite each otherEach agent has its own directory
Conflicts during workConflicts resolved at merge time
Must coordinate file accessAgents work independently
Sequential to avoid collisionsTrue parallel execution
Single branchOne branch per agent

Next Session

This completes Module 2: Multi-Agent Systems. You now understand task graphs, background tasks, team communication, protocols, autonomous agents, and worktree isolation.

In Module 3, we shift to the systems that configure and extend Claude Code. Session 13 starts with Control Protocol — how external tools send structured commands to Claude Code and receive responses, enabling IDE integration and programmatic control.