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
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 addrefuses to check out a branch that's already checked out in another worktree.--forceoverrides 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:
claude --worktree feature-authAccording 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
claudethere once and accept the trust dialog. Non-interactive runs with-pskip this check.
Add the worktree folder to .gitignore so its contents don't show up as untracked files in your main checkout:
.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:
{
"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:
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:
.env
.env.local
config/secrets.jsonThis 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 plaingit lfs install, which writes to your global config, isn't affected. To get the real files, rungit lfs pullinside 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:
---
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:
- File edits: blocks an
Edit,WriteorNotebookEditcall that targets a path in the main checkout. - 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.
- Git redirects: blocks a command that points git at the main checkout through
git -C,--git-dir, aGIT_DIRorGIT_WORK_TREEvariable, or acdinto the main checkout before running git. - 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> --resumecommand 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:
git worktree list
git worktree unlock .claude/worktrees/feature-auth
git worktree remove .claude/worktrees/feature-authgit 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:
git worktree add ../project-feature-a -b feature-a
git worktree add ../project-bugfix fix-issue-456
cd ../project-feature-a
claudeThe 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
- Make at least one commit and add
.claude/worktrees/to.gitignore. - Write a
.worktreeincludefor your env files. - Start each session with
claude --worktree <name>. - Add
isolation: worktreeto subagents that edit files in parallel. - Give each worktree its own ports and databases.
- Remove worktrees left by
-pruns 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
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.