Git Worktrees for AI Agent Development: Parallel Workflows Without Conflicts

Learn how to use git worktrees to run multiple AI coding agents on the same repository without merge conflicts or context contamination.

Git Worktrees for AI Agent Development: Parallel Workflows Without Conflicts

You have three AI coding agents running on the same project. Claude Code is refactoring your authentication module. Codex is writing tests for the API layer. Aider is updating the frontend to match a new design spec. They are all working in the same directory, on the same branch, modifying files at the same time.

It takes about ninety seconds before everything falls apart.

One agent overwrites another agent's changes. A half-written file gets picked up as context by the wrong agent. You end up with merge conflicts in files that no human touched. The git history becomes an unreadable mess of interleaved, contradictory commits.

This is the fundamental problem with running multiple AI agents on a single codebase: they need filesystem isolation, but they also need to share the same repository history. Git worktrees solve this problem cleanly.

What Git Worktrees Are

A git worktree is an additional working directory linked to your existing repository. When you run git worktree add, git creates a new directory with its own checked-out branch and its own working tree, but it shares the same .git object store, the same commit history, and the same remote configuration as the original.

Think of it this way: your repository has one .git directory that contains all the objects, refs, and configuration. A worktree is just another window into that same repository. Each worktree can have a different branch checked out, different staged changes, and different modified files, but they all share the same underlying git database.

This is different from cloning the repository again. A clone duplicates the entire object store, which wastes disk space and creates a separate history that you have to keep in sync. Worktrees share everything except the working directory and the current branch pointer.

For AI agent workflows, this means each agent gets its own isolated filesystem to read and write, while all changes flow through the same repository. No file locking conflicts. No context contamination. Clean merges when the work is done.

Basic Commands

Git worktrees are built into git (version 2.5+). No plugins or extensions needed.

Creating a worktree

git worktree add ../myproject-feature-auth feature/auth

This creates a new directory at ../myproject-feature-auth, checks out the feature/auth branch in it, and links it back to your main repository. If the branch does not exist yet, add -b to create it:

git worktree add -b feature/auth ../myproject-feature-auth main

This creates a new branch feature/auth based on main and checks it out in the new worktree directory.

Listing worktrees

git worktree list

Output:

/home/user/myproject                  abc1234 [main]
/home/user/myproject-feature-auth     def5678 [feature/auth]
/home/user/myproject-feature-tests    ghi9012 [feature/tests]

Each line shows the directory path, the current commit hash, and the checked-out branch.

Removing a worktree

When you are done with a worktree, remove it:

git worktree remove ../myproject-feature-auth

This deletes the worktree directory and cleans up the internal tracking. If the worktree has uncommitted changes, git will refuse to remove it unless you pass --force.

Pruning stale worktrees

If a worktree directory was deleted manually (without using git worktree remove), the internal references become stale. Clean them up:

git worktree prune

This removes any worktree entries whose directories no longer exist on disk.

Setting Up Worktrees for AI Agent Workflows

The core pattern is simple: one worktree per agent, one branch per task.

Directory structure

Start with your main project directory and create sibling worktrees:

# Your main repository
cd ~/projects/webapp

# Create worktrees for each agent/task
git worktree add -b feature/auth ../webapp-agent-auth main
git worktree add -b feature/api-tests ../webapp-agent-tests main
git worktree add -b feature/frontend-redesign ../webapp-agent-frontend main

Your filesystem now looks like this:

~/projects/
  webapp/                        # main branch (your primary working copy)
  webapp-agent-auth/             # feature/auth branch (Agent 1)
  webapp-agent-tests/            # feature/api-tests branch (Agent 2)
  webapp-agent-frontend/         # feature/frontend-redesign branch (Agent 3)

Each directory is a full, independent working tree. You can cd into any of them, run builds, start dev servers, or point an AI agent at them. Changes in one directory do not affect the others.

Naming conventions

Pick a convention and stick with it. Two patterns that work well:

Project-agent-task: Use when you think in terms of which agent is assigned where.

git worktree add ../webapp-claude-auth
git worktree add ../webapp-codex-tests
git worktree add ../webapp-aider-frontend

Project-feature-name: Use when you think in terms of the work being done, regardless of which agent handles it.

git worktree add ../webapp-feature-auth
git worktree add ../webapp-feature-tests
git worktree add ../webapp-feature-frontend

The second convention is generally better because you might reassign agents between tasks, and directory names should describe the content, not the tool.

Install dependencies per worktree

Each worktree is an independent directory, which means language-specific dependency directories (node_modules, venv, target, etc.) need to exist in each one:

cd ~/projects/webapp-agent-auth
npm install

cd ~/projects/webapp-agent-tests
npm install

cd ~/projects/webapp-agent-frontend
npm install

This is the main downside of worktrees compared to branch switching: you pay the disk cost of duplicated dependencies. For a typical Node.js project, this is a few hundred megabytes per worktree. For most machines in 2026, this is negligible. If it matters, use symlinks for large, immutable dependency directories or tools like pnpm that use a shared store.

Practical Workflow Examples

Example 1: Two agents working in parallel

You need to add a new API endpoint and simultaneously update the frontend to consume it. Without worktrees, these changes would collide because both touch shared configuration files, route definitions, and type definitions.

Set up:

cd ~/projects/webapp
git worktree add -b feature/api-users ../webapp-api main
git worktree add -b feature/ui-users ../webapp-ui main

Start your agents in separate terminals:

# Terminal 1: Backend agent
cd ~/projects/webapp-api
claude-code
> "Add a REST endpoint at /api/users with CRUD operations.
>  Use the existing database models and auth middleware."

# Terminal 2: Frontend agent
cd ~/projects/webapp-ui
codex
> "Create a user management page at /admin/users.
>  Include a data table with search, pagination, and edit forms."

Both agents work simultaneously without interference. When both are done:

# Merge backend work
cd ~/projects/webapp
git merge feature/api-users

# Merge frontend work
git merge feature/ui-users

# Clean up
git worktree remove ../webapp-api
git worktree remove ../webapp-ui
git branch -d feature/api-users feature/ui-users

If the merges conflict (unlikely when the agents worked on separate parts of the codebase, but possible with shared files like route configs), you resolve them once during the merge rather than dealing with live file conflicts during development.

Example 2: One agent codes, another reviews

This is the AI equivalent of pair programming. One agent writes the implementation. A second agent, working from a copy of the same branch, reviews the changes.

Set up:

cd ~/projects/webapp
git worktree add -b feature/payments ../webapp-implement main

Start the implementation agent:

cd ~/projects/webapp-implement
claude-code
> "Implement Stripe payment processing. Add checkout flow,
>  webhook handling, and subscription management."

Let it work. When it commits, the commits are immediately visible to any worktree that shares the repository. Create a review worktree from the same branch:

cd ~/projects/webapp
git worktree add ../webapp-review feature/payments

Now start the review agent:

cd ~/projects/webapp-review
codex
> "Review all changes on this branch compared to main.
>  Check for security issues, missing error handling,
>  and test coverage gaps. List specific files and line numbers."

The review agent reads the implementation agent's committed work without being able to accidentally modify it (since both worktrees are on the same branch, git will prevent simultaneous edits to the same branch, but the reviewer only reads). In practice, you would typically put the reviewer on a separate branch:

git worktree add -b review/payments ../webapp-review feature/payments

This gives the review agent its own branch to write review notes or suggested fixes without affecting the implementation branch.

Example 3: Safe experimentation with risky refactors

You want an agent to try a large refactor, but you are not confident it will work. Instead of risking your working directory, isolate the experiment in a worktree.

cd ~/projects/webapp
git worktree add -b experiment/new-orm ../webapp-experiment main

Let the agent loose:

cd ~/projects/webapp-experiment
claude-code
> "Migrate the entire data layer from Sequelize to Drizzle ORM.
>  Update all models, queries, and migrations."

If it works, merge it. If it does not, throw it away:

# Success path
cd ~/projects/webapp
git merge experiment/new-orm
git worktree remove ../webapp-experiment
git branch -d experiment/new-orm

# Failure path
git worktree remove --force ../webapp-experiment
git branch -D experiment/new-orm

The experiment never touched your main working directory. Your main branch is exactly as it was.

Worktrees + tmux/zellij

The natural complement to worktrees is a terminal multiplexer. Each pane or window runs in a different worktree, each with its own agent. You can see all the work happening at once.

tmux setup script

Create a script that sets up a full multi-agent workspace:

#!/bin/bash
# setup-agent-workspace.sh

PROJECT="webapp"
BASE_DIR="$HOME/projects"

# Create worktrees
cd "$BASE_DIR/$PROJECT"
git worktree add -b feature/backend "../${PROJECT}-backend" main 2>/dev/null
git worktree add -b feature/frontend "../${PROJECT}-frontend" main 2>/dev/null
git worktree add -b feature/tests "../${PROJECT}-tests" main 2>/dev/null

# Create tmux session with three panes
tmux new-session -d -s agents -c "$BASE_DIR/${PROJECT}-backend"
tmux rename-window -t agents:0 'backend'

tmux new-window -t agents -c "$BASE_DIR/${PROJECT}-frontend"
tmux rename-window -t agents:1 'frontend'

tmux new-window -t agents -c "$BASE_DIR/${PROJECT}-tests"
tmux rename-window -t agents:2 'tests'

# Add a fourth window in the main repo for merging
tmux new-window -t agents -c "$BASE_DIR/${PROJECT}"
tmux rename-window -t agents:3 'main'

# Attach to the session
tmux attach -t agents

Run it and you get four named windows, each in its own worktree. Start an agent in each window and let them work.

zellij layout

For zellij, define a layout file at ~/.config/zellij/layouts/agents.kdl:

layout {
    pane size=1 borderless=true {
        plugin location="zellij:tab-bar"
    }

    pane split_direction="vertical" {
        pane {
            name "Backend Agent"
            cwd "/home/user/projects/webapp-backend"
        }
        pane split_direction="horizontal" {
            pane {
                name "Frontend Agent"
                cwd "/home/user/projects/webapp-frontend"
            }
            pane {
                name "Test Agent"
                cwd "/home/user/projects/webapp-tests"
            }
        }
    }

    pane size=2 borderless=true {
        plugin location="zellij:status-bar"
    }
}

Launch it:

zellij --layout agents

You get a three-pane layout with each pane starting in a different worktree directory. Start your agents and work.

Merging Work Back Together

When your agents finish their tasks, you need to bring all the branches together.

The straightforward merge

If the agents worked on separate parts of the codebase (the common case), merges are clean:

cd ~/projects/webapp
git checkout main

# Merge each feature branch
git merge feature/backend
git merge feature/frontend
git merge feature/tests

Each merge applies cleanly because the changes do not overlap.

Handling conflicts

When two agents modified the same file (shared configuration, type definitions, route tables), you will get merge conflicts. This is expected and normal. The advantage of the worktree approach is that you deal with conflicts at merge time, in one controlled step, rather than having agents silently overwrite each other's work in real time.

Resolve conflicts the usual way:

git merge feature/frontend
# CONFLICT in src/routes/index.ts
# Edit the file to resolve
git add src/routes/index.ts
git commit

If you expect conflicts and want to review before committing:

git merge --no-commit feature/frontend
# Review all staged changes
git diff --cached
# If satisfied:
git commit
# If not:
git merge --abort

Cleanup

After merging, remove the worktrees and delete the branches:

# Remove worktrees
git worktree remove ../webapp-backend
git worktree remove ../webapp-frontend
git worktree remove ../webapp-tests

# Delete merged branches
git branch -d feature/backend feature/frontend feature/tests

# Prune any stale worktree references
git worktree prune

Make cleanup a habit. Stale worktrees waste disk space and clutter git worktree list output.

Worktrees vs. Clones vs. Stash

There are other ways to get filesystem isolation. Here is why worktrees are usually the better choice for AI agent workflows.

Separate git clones

You can clone the repository multiple times:

git clone repo ~/projects/webapp-clone-1
git clone repo ~/projects/webapp-clone-2

Downsides:

  • Each clone duplicates the entire object store. For a repository with significant history, this means hundreds of megabytes or gigabytes of wasted disk space per clone.
  • Clones have independent remotes and fetch states. You have to git fetch in each clone separately.
  • Branches created in one clone are not visible in another until pushed to a remote and fetched.
  • Commits in one clone are not available in another without a push/fetch cycle.

Worktrees share the object store, so there is zero duplication. Commits made in any worktree are immediately visible to all other worktrees because they all reference the same .git database.

Git stash

Stashing lets you temporarily shelve changes:

git stash
# Switch context
git stash pop

Downsides:

  • Stash is sequential, not parallel. You can only have one set of unstashed working changes at a time.
  • Stashing and unstashing is error-prone. Complex stash stacks become confusing quickly.
  • It does not help with the core problem: two agents cannot work on different branches in the same directory simultaneously.

Stash is useful for quick context switches when you are working alone. It is not a solution for parallel agent work.

Summary

Approach Disk cost Parallel work Shared history Setup effort
Worktrees Low (shared objects) Yes Yes (immediate) Low
Clones High (duplicated) Yes No (push/fetch) Medium
Stash None No N/A None

Worktrees are the right tool for parallel agent workflows.

Tips and Pitfalls

Do not check out the same branch in two worktrees

Git prevents this by default, and for good reason. If two worktrees share a branch and both make commits, the branch pointer becomes inconsistent. If you try:

git worktree add ../webapp-second main

And main is already checked out in your primary worktree, git will refuse:

fatal: 'main' is already checked out at '/home/user/projects/webapp'

Always create a new branch for each worktree. This is the natural workflow anyway: each agent should be working on its own feature branch.

Clean up worktrees when done

Worktrees accumulate over time if you do not clean up. Each one takes disk space (especially with node_modules or other dependency directories) and clutters your project area. After merging a branch, immediately remove its worktree:

git worktree remove ../webapp-feature-x
git branch -d feature/x
git worktree prune

Watch disk usage with per-worktree dependencies

Each worktree needs its own node_modules, Python venv, Rust target directory, or equivalent. For a typical JavaScript project, that is 200-500 MB per worktree. Three worktrees means up to 1.5 GB of duplicated dependencies.

Mitigations:

  • Use pnpm instead of npm. pnpm uses a content-addressable store and hardlinks, so shared packages are not duplicated on disk.
  • For Python, use a shared virtualenv if the agents are not modifying dependencies.
  • Delete worktrees promptly when finished.
  • If disk is tight, work with fewer parallel worktrees.

Use .gitignore properly

Agent tools sometimes create artifacts: log files, conversation histories, cache directories. Make sure your .gitignore covers these so they do not leak into commits from any worktree:

# AI agent artifacts
.claude/
.codex/
.aider*
.cursor/

# Dependencies (per worktree)
node_modules/
venv/
.venv/
target/

Since all worktrees share the same .gitignore (it is part of the repository), you only need to set this up once.

Shared hooks and configuration

All worktrees share the same .git directory (or, more precisely, the worktrees reference the main repository's .git). This means:

  • Git hooks (.git/hooks/) apply to all worktrees.
  • Git config (.git/config) is shared.
  • Remotes are shared.

This is generally an advantage: pre-commit hooks, commit message templates, and remote configuration work the same everywhere. But be aware that a hook that references paths relative to the working directory might behave unexpectedly in a worktree with a different directory structure.

Keep your main worktree clean

Your primary working directory (the original clone) should stay on main or your default branch. Use it as the merge target and the place where you review the combined result of all agent work. Let the agents do their work in the secondary worktrees, and keep the primary worktree as your clean baseline.

# Primary worktree: stay on main, use for merging
cd ~/projects/webapp
git checkout main

# Agent worktrees: feature branches only
cd ~/projects/webapp-agent-auth     # on feature/auth
cd ~/projects/webapp-agent-tests    # on feature/tests

This convention makes it clear where the source of truth is and prevents confusion about which directory has the latest merged state.


Agents UI makes managing multiple agent sessions across worktrees easier with built-in session management and persistent terminal state. Each session can point to a different worktree, giving you a visual overview of all parallel agent work in one window. Learn more about Agents UI.

Try Agents UI

A native terminal for AI coding agents with persistent sessions, SSH workflows, and built-in editing.