Atlas
TechnicalHow-to

Claude Code Worktrees: Run Parallel Sessions Safely

How to run parallel Claude Code sessions with git worktrees: the --worktree flag, .worktreeinclude, subagent isolation, cleanup rules and merging back.

The short version

  • To stop several Claude Code sessions from overwriting each other's edits, give each session its own git worktree: a separate working folder linked to the same repository.
  • Running claude --worktree <name> creates .claude/worktrees/<name>/ on a new branch called worktree-<name> and starts the session there. The repository needs at least one commit first.
  • A new worktree has no installed dependencies or .env files. List gitignored config files in a .worktreeinclude file and Claude Code copies them into each new worktree.
  • Claude Code blocks some edits and git commands that reach back into the main checkout, but the docs say this is not a security boundary. Worktrees also don't separate ports, databases or the final merge.
  • Worktrees from non-interactive -p runs are not cleaned up automatically. Remove them with git worktree remove, running git worktree unlock first if git says the worktree is locked.
On this page
  1. The short version
  2. Why parallel agents need git worktrees
  3. Start Claude Code in a worktree
  4. Set up the worktree environment
  5. Isolate subagents with worktrees
  6. What Claude Code enforces inside a worktree
  7. Clean up worktrees
  8. Manage worktrees manually
  9. Merging parallel work back
  10. Checklist
  11. Questions people ask

To run several Claude Code sessions on one repository without them overwriting each other's edits, give each session its own git worktree. Claude Code does this with one flag, claude --worktree <name>. It creates a separate checkout on a new branch and starts the session inside it. This guide covers setup, the files a new worktree is missing, subagent isolation, cleanup, and the parts you still have to handle yourself.

Why parallel agents need git worktrees

Two agent sessions in one working directory share one set of files. One session's refactor can land in the middle of the other's test run, and both write to the same index. Separate branches don't solve this, because a single checkout can only have one branch checked out at a time.

A git worktree is an extra working directory linked to the same repository. Per the git documentation, each worktree gets its own HEAD and index. Refs under refs/, branches and tags included, are shared, apart from a few per-worktree ones such as refs/bisect. The repository's config file is also shared by default. What that means for you:

  • A branch created or updated in one worktree is visible from all the others immediately, with no push or fetch.
  • Each worktree has its own files on disk, so edits in one don't touch the others.
  • By default, git worktree add refuses to check out a branch that's already checked out in another worktree. --force overrides this.

That last rule keeps agents apart: each session ends up on its own branch.

Start Claude Code in a worktree

Pass --worktree (or -w) with a name:

bash
claude --worktree feature-auth

According to the Claude Code documentation, this creates the worktree under .claude/worktrees/feature-auth/ at the repository root, on a new branch named worktree-feature-auth, and starts the session there. Run the same command in a second terminal with a different name to get a second isolated session. If you leave out the name, Claude generates one, such as bright-running-fox. Pass a name whose directory already exists and Claude Code reopens that worktree rather than creating a new one.

There are two prerequisites:

  • At least one commit. A worktree is created from an existing commit. In a repository with no commits, the command fails with Failed to resolve base branch "HEAD": git rev-parse failed.
  • Workspace trust. Interactive runs need it. If you haven't used Claude in that directory before, run claude there once and accept the trust dialog. Non-interactive runs with -p skip this check.

Add the worktree folder to .gitignore so its contents don't show up as untracked files in your main checkout:

text
.claude/worktrees/

You can also ask Claude to "work in a worktree" during a session, and it creates one with its EnterWorktree tool. If Claude tries to enter a path outside the repository's .claude/worktrees/ directory, Claude Code asks for your approval first. Neither a permission rule nor "don't ask again" turns this prompt off. Only bypassPermissions mode skips it. The prompt arrived in v2.1.206. Before that, Claude could enter any existing worktree without asking. Several other behaviors in this guide also depend on recent 2.1.x versions, so on an older version some of them will work differently.

Choose what the worktree branches from

By default, a new worktree branches from the repository's default branch on the remote (usually main), so it starts from a clean tree. To branch from your current local HEAD instead, bringing along unpushed commits and feature-branch state, set worktree.baseRef in settings:

json
{
  "worktree": {
    "baseRef": "head"
  }
}

The setting has two values: "fresh" (the default) and "head". Inside a worktree, "head" means that worktree's HEAD, not the main checkout's. You can't set it to a branch name. To start from a specific existing branch, create the worktree with git yourself (see below).

To review or continue a pull request in isolation, pass its number with a # prefix. Quote it so your shell doesn't treat # as the start of a comment:

bash
claude --worktree "#1234"

Claude Code fetches that pull request's head commit from origin and creates the worktree at .claude/worktrees/pr-1234. You can also pass a GitHub pull request URL or a GitLab merge request URL. Claude Code reads only the number from the URL and always fetches from origin.

Set up the worktree environment

A worktree is a fresh checkout of tracked files. It has none of your gitignored local files, so expect no node_modules, virtualenv, build cache or .env. Set up each worktree, either by asking Claude to install dependencies or by running your project's setup in the worktree directory yourself.

For gitignored files such as environment configs, add a .worktreeinclude file at the project root. It uses .gitignore syntax. Claude Code copies files that match a pattern and are gitignored into each new worktree, so tracked files are never duplicated. This example comes from the documentation:

text
.env
.env.local
config/secrets.json

This applies to every worktree Claude Code creates with git: --worktree sessions, subagent worktrees and parallel sessions in the desktop app. It doesn't apply if you replaced worktree creation with a WorktreeCreate hook. In that case, copy the files in your hook script.

Two things to plan for when several worktrees run at once:

  • Shared local resources. The Claude Code docs don't cover this, but separate file trees don't give you separate ports, databases or Docker containers. If every worktree starts a dev server on the same port or migrates the same local database, the sessions will collide. Give each worktree its own port or database name, for example through its env file.
  • Git LFS. If you set up LFS with git lfs install --local, worktrees that Claude Code creates contain LFS pointer files, not the real files. Claude Code skips filter drivers defined in the repository's own config when it creates a worktree, because a filter driver is a shell command that anything able to write to the repository could have planted. A plain git lfs install, which writes to your global config, isn't affected. To get the real files, run git lfs pull inside the worktree.

Isolate subagents with worktrees

Subagents that Claude spawns can each get their own worktree too, so their parallel edits don't conflict. Ask Claude to "use worktrees for your agents," or make it permanent for a custom subagent by adding isolation: worktree to its frontmatter:

markdown
---
name: refactorer
description: Applies mechanical refactors across many files
isolation: worktree
---

Apply the requested refactor across every affected file, then run the tests
and report the results.

Put that file in .claude/agents/. Each run gets a temporary worktree, and Claude Code removes it automatically if the subagent finishes without changes. A worktree with changes stays on disk. A periodic sweep removes subagent and background-session worktrees once they are older than your cleanupPeriodDays setting, but it leaves any worktree that still has changed or untracked files or unpushed commits. Subagent worktrees use the same base-branch setting as --worktree. If subagents need to build on unpushed work, set worktree.baseRef to "head".

What Claude Code enforces inside a worktree

While a session is isolated in a worktree, Claude Code blocks some tool calls that would reach back into the main checkout. The same checks apply to subagents spawned from that session. The documentation lists four:

  1. File edits: blocks an Edit, Write or NotebookEdit call that targets a path in the main checkout.
  2. Command working directory: blocks a command whose working directory resolves to the main checkout, or whose working directory it can't confirm stays outside it.
  3. Git redirects: blocks a command that points git at the main checkout through git -C, --git-dir, a GIT_DIR or GIT_WORK_TREE variable, or a cd into the main checkout before running git.
  4. Command shape: blocks a command when Claude Code can't tell from its text that any git it runs stays inside the worktree. You can't turn this check off.

PowerShell commands get only the working-directory check. The documentation also spells out the limits: none of the checks tracks which files a shell command writes, so a cp or shell redirect into the main checkout isn't caught. Those commands fall under your normal permission and sandbox settings. Treat worktree isolation as protection against accidents, not as a security boundary.

Some things are shared on purpose. If you choose "Yes, and don't ask again" for a Bash command in a worktree session, the rule goes into the main checkout's .claude/settings.local.json. It then applies in the main checkout and in every other worktree of the repository, and it stays after the worktree is removed. On Windows, and in a few other cases the docs list, the rule stays with the worktree instead. Plugins installed at project scope from the main checkout also load in its worktrees.

Clean up worktrees

When you exit an interactive worktree session, Claude Code checks for anything removal would destroy: changed or untracked files, uncommitted work in checked-out submodules, and new commits.

  • Clean worktree: for an unnamed session, Claude removes the worktree and its branch automatically. A named session asks first.
  • Worktree with work in it: you choose whether to keep it or remove it. If you keep it, Claude Code prints a claude --worktree <name> --resume command so you can come back later. Removing it deletes the directory, the branch and all the work in them.
  • State can't be verified: Claude Code asks you rather than removing it automatically.

Non-interactive runs (-p) have no exit prompt, so Claude doesn't clean up their worktrees. The lock Claude Code put on each one at creation also stays until a later session's sweep releases it. Remove these worktrees with git, unlocking first if git refuses because the worktree is locked:

bash
git worktree list
git worktree unlock .claude/worktrees/feature-auth
git worktree remove .claude/worktrees/feature-auth

git worktree remove only removes clean worktrees, meaning no untracked files and no changes to tracked files. A worktree that isn't clean, or that contains submodules, needs --force, so check first that nothing in it matters. If you deleted a worktree directory by hand, git worktree prune removes the leftover administrative data. Add -n to see what it would remove without removing anything.

Manage worktrees manually

Use git directly when you need an existing branch or a location outside the repository:

bash
git worktree add ../project-feature-a -b feature-a
git worktree add ../project-bugfix fix-issue-456
cd ../project-feature-a
claude

The first command creates a new branch. The second checks out a branch that already exists. Claude Code's sweep never removes worktrees you created yourself with git worktree add, so cleaning those up is your job.

Merging parallel work back

Worktrees keep work apart, but they don't put it back together. Five sessions on five branches means five merges, and any conflicts the worktrees postponed show up then. Some habits that help:

  • Split work by area, not by size. Two agents editing the same module will conflict however well their files are isolated.
  • Merge often. Short-lived branches drift less from main.
  • Run your full checks on the merged result, not only on each branch. Two branches can each pass alone and still break when combined.

Atlas, an AI engineering team built on Claude Code, handles this step for its own engineers. Each engineer works in its own copy of the code, so engineers never edit the same files under each other. Finished work goes to a landing train, which merges up to six finished branches, runs the project's own checks once on the combined result, and splits a failing batch until it finds the branch that broke it. Main's history is never rewritten. Each test run also gets its own copy of the project's database per worker, which covers part of the shared-database problem described above.

Checklist

  1. Make at least one commit and add .claude/worktrees/ to .gitignore.
  2. Write a .worktreeinclude for your env files.
  3. Start each session with claude --worktree <name>.
  4. Add isolation: worktree to subagents that edit files in parallel.
  5. Give each worktree its own ports and databases.
  6. Remove worktrees left by -p runs yourself.

For more on running a team of AI engineers, see the Atlas home page.

Questions people ask

How do I run multiple Claude Code sessions on the same repo without conflicts?

Run claude --worktree <name> in each terminal, using a different name each time. Each session gets its own checkout under .claude/worktrees/ on its own new branch, so edits in one don't touch the others. The repository needs at least one commit first.

What does claude --worktree actually create?

It creates a worktree at .claude/worktrees/<name>/ in your repository root, on a new branch named worktree-<name>, and starts the session there. By default the branch starts from the remote's default branch. Set worktree.baseRef to "head" to start from your current local HEAD instead. If you leave out the name, Claude generates one, such as bright-running-fox.

Why is my .env file missing in a new Claude Code worktree?

A worktree is a fresh checkout of tracked files, so gitignored files such as .env, node_modules or a virtualenv aren't there. Add a .worktreeinclude file at the project root, using .gitignore syntax, and Claude Code copies matching gitignored files into each new worktree. You still have to install dependencies yourself.

Does Claude Code clean up worktrees automatically?

Partly. When you exit an interactive session, a clean worktree from an unnamed session is removed automatically. A named session asks first, and a worktree with work in it asks whether to keep or remove it. Subagent worktrees without changes are removed when the subagent finishes. Worktrees from -p runs aren't cleaned up: remove them with git worktree remove, running git worktree unlock first if git says the worktree is locked.

Are Claude Code worktrees a security boundary?

No. The documentation says to treat worktree isolation as protection against accidents. Claude Code blocks edits, commands and git redirects that target the main checkout, but it doesn't track which files a shell command writes, so a cp or shell redirect into the main checkout isn't caught.

Sources

  1. Run parallel sessions with worktrees – Claude Code Docs
  2. Common workflows – Claude Code Docs
  3. git-worktree Documentation

Researched and drafted with Claude, then checked against the sources above. Atlas is an independent product, not affiliated with Anthropic or OpenAI. Claude and Claude Code are trademarks of Anthropic; Codex is a product of OpenAI.