Claude Code worktrees: parallel sessions without collisions
Two Claude Code sessions in the same directory are a recipe for trouble: one builds a feature, the other fixes a bug, and both write to the same files. Git worktrees have solved this for humans for years, and Claude Code has the route built in. This article explains how to start a session in a worktree, what gets copied and what does not, how isolation is enforced, when cleanup happens and how subagents get their own worktrees. It is based on the official documentation as of September 2026.
What a worktree is
A git worktree is a second working directory of the same repository: its own files, its own branch, but the same history and the same remote as your main checkout. What you change in one worktree stays there. If every Claude Code session runs in its own worktree, one session can build a feature while a second fixes a bug, without the two ever getting in each other’s way.
Worktrees require a git repository with at least one commit. For other version control systems the git logic can be replaced through hooks; more on that at the end. In the desktop app, every new session gets its own worktree automatically.
Starting a session in a worktree
claude --worktree feature-auth
# short:
claude -w feature-auth
Claude Code creates the worktree under .claude/worktrees/feature-auth/ in the repository, on a new branch worktree-feature-auth, and starts there. Run the same command with a different name in a second terminal and the second session runs isolated alongside. Leave out the name and Claude Code generates one such as bright-running-fox.
Two things first: interactive sessions require workspace trust; if you have never started Claude in that directory, do it once without the flag and accept the dialog. And add .claude/worktrees/ to your .gitignore, otherwise the worktree contents show up as untracked files in your main checkout.
What is missing in the worktree, and how to get it in
A worktree is a fresh checkout. Dependencies are not installed, and everything git ignores is absent: .env, local configuration, secrets. Install the dependencies as usual, or ask Claude to. For the ignored files there is .worktreeinclude in the project root, in .gitignore syntax:
# .worktreeinclude
.env
.env.local
config/secrets.json
Only files that match a pattern and are gitignored get copied; tracked files are never duplicated. This applies to every worktree Claude Code creates with git: via --worktree, for subagents and in the desktop app.
Sending Claude into a worktree mid-session
You do not have to restart the session. “Work in a worktree” is enough, and Claude creates one with the EnterWorktree tool. From there Claude can switch directly to another worktree under .claude/worktrees/; the previous one stays on disk untouched. A path outside that directory needs your approval, because the working directory, write access and project configuration move with it.
One trap for hook users: ${CLAUDE_PROJECT_DIR} keeps pointing at the project root where the session started. A hook gets the worktree path from the cwd field in its input data.
How isolation is enforced
With Claude Code, isolation is not a recommendation but a block. While a session runs in a worktree, Claude Code refuses four kinds of calls, and it does so for every subagent that session spawns:
- file edits via Edit, Write or NotebookEdit targeting paths in the main checkout
- commands whose working directory is in the main checkout or cannot be verified to stay outside it
- git redirects into the main checkout, for example via
git -C,--git-dir,GIT_DIR,GIT_WORK_TREEor acdbefore the git call - command shapes that cannot be traced without running them, such as brace expansion and heredocs with unquoted delimiters; this check cannot be turned off
Claude sees each refusal as a tool error that names the worktree and says how to proceed, for example by splitting a command into plain single steps.
Cleanup on exit
When you leave an interactive worktree session, Claude Code checks whether work would be lost: changed or new files, new commits.
- Worktree clean: for an unnamed session it is removed together with its branch; a named session asks first so you can keep it.
- Worktree with work: Claude Code asks whether to keep or remove. Removing deletes directory and branch with everything in them.
- Non-interactive with
-p: no dialog, no cleanup. Remove withgit worktree remove, aftergit worktree unlockif it is locked.
If you resume a session later, Claude Code returns to its worktree, also with --continue and --resume. If the directory no longer exists, the session continues where you launched Claude and the binding is cleared.
Subagents with their own worktree
If several subagents are to change files in parallel, each gets its own worktree. Either ask Claude (“use worktrees for your agents”), or make it permanent for a custom agent:
---
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.
Each subagent receives a temporary worktree. If it ends without changes, the worktree is removed immediately; with changes it stays until a periodic sweep can remove it safely after cleanupPeriodDays. While the agent runs, Claude Code holds a lock on the worktree so that no concurrent sweep takes it away. How to define and invoke subagents is covered in the article on subagents in Claude Code.
Base branch, pull requests, reuse
A new worktree branches by default from the repository’s default branch on the remote, usually main. If you want subagents to work on in-progress changes, switch the setting:
{
"worktree": {
"baseRef": "head"
}
}
The setting knows only two values, fresh (default) and head; it does not accept a branch name, that is what the manual route below is for. With "head" the worktree starts from your current local HEAD, including unpushed commits. To branch from a specific pull request, pass its number: claude --worktree "#1234" creates the worktree under .claude/worktrees/pr-1234 from the pull request’s head; the quotes stop the shell from reading the hash sign as a comment. A name whose directory already exists opens the existing worktree. If it is clean, still on its own branch and without commits of its own, Claude Code resets it to the default branch on the way, provided the setting is at its default fresh.
What worktrees share with the main checkout
- the repository’s
.gitdirectory;git commitworks inside a worktree even with the sandbox enabled - plugins installed at project scope, without reinstalling per worktree
- permissions: a saved approval for a command in a worktree (the option not to ask again) is written to the main checkout’s
.claude/settings.local.jsonand applies in every worktree of the repository
Worktrees by hand
For an existing branch, or a location outside the repository, create the worktree with git yourself and start Claude in it:
git worktree add ../project-feature-a -b feature-a
cd ../project-feature-a
claude
git worktree list
git worktree remove ../project-feature-a
And a note on CLAUDE.md: a CLAUDE.local.md excluded via .gitignore exists only in the worktree where you created it. Personal instructions that should apply in every worktree are imported from your home directory instead, for example with @~/.claude/my-project.md.
Other version control systems
For SVN, Perforce or Mercurial, the hooks WorktreeCreate and WorktreeRemove replace the git logic: the hook reads the name from its input, creates a working directory and prints its path. .worktreeinclude is not processed then; copying local files is the hook’s job.
Conclusion
Worktrees turn “one session after another” into “several sessions side by side”, without you having to keep track of branch switches and half-finished files. Getting started is one flag; cleanup is handled by Claude Code as long as you work interactively. Once .worktreeinclude is in place, all that is left to do in a new worktree is installing the dependencies.
Further reading
- Claude Code subagents: delegate work and keep your context clean
- How to create and structure CLAUDE.md
- Claude Code cheat sheet
Frequently Asked Questions
Frequently Asked Questions
What is a git worktree?
An additional working directory of the same repository with its own files and its own branch. History and remote are shared. Changes in one worktree never touch the files in another.
How do I start Claude Code in a worktree?
With claude –worktree name, or -w name for short. Claude Code creates the worktree under .claude/worktrees/name/ in the repository, on a new branch worktree-name, and starts there. Without a name, Claude Code generates one.
Why is my .env missing in the worktree?
A worktree is a fresh checkout; files that git ignores are not in it. Create a .worktreeinclude in the project root and list the files in .gitignore syntax. Claude Code then copies them into every new worktree.
What happens to the worktree when I end the session?
If it is clean, Claude Code removes it together with its branch (for named sessions after asking). If it holds work, Claude Code asks whether to keep or remove it. Non-interactive runs with -p do not clean up.
Can a subagent work in its own worktree?
Yes. Either ask Claude to do so, or set isolation: worktree in the agent file’s frontmatter. The agent gets a temporary worktree that is removed automatically if it ends without changes; with changes it stays until a later sweep can remove it without losing work.
Which branch does a new worktree start from?
By default the repository’s default branch on the remote, usually main. With worktree.baseRef set to head in your settings, the worktree starts from your current local HEAD instead, including unpushed commits.
