Worktrees
A git worktree is a second working directory with its own files and branch that shares one repository history, and Claude Code uses worktrees to keep parallel sessions and subagents from editing the same files.
What it is
A worktree is a real checkout on disk with its own HEAD, its own branch, and its own file contents, all backed by the same .git directory as your main checkout. Pass claude --worktree feature-auth — or -w — and Claude Code creates one at .claude/worktrees/feature-auth/ on a new branch worktree-feature-auth, then starts the session inside it. Omit the name and it generates one such as bright-running-fox.
Isolation is enforced, not just conventional. While a session is in a worktree, Claude Code blocks an Edit, Write, or NotebookEdit whose path lands in the main checkout; blocks a Bash, PowerShell, or Monitor command whose working directory resolves there; and blocks a Bash or Monitor command that redirects git into the main checkout through git -C, --git-dir, GIT_DIR, GIT_WORK_TREE, or a cd before the git call. The same checks cover every subagent spawned from that session.
Subagents can be isolated the same way. Add isolation: worktree to a subagent’s frontmatter and every run gets a temporary worktree, branched by default from the repository’s default branch rather than your HEAD. Claude Code removes it automatically when the subagent finishes without changes.
What it does for you
- It lets two sessions work at once without one overwriting the other. One builds a feature while the other fixes a bug, in separate directories on separate branches.
- It makes parallel subagent edits safe. Without isolation, two agents refactoring the same files interleave writes and the last one wins.
- It keeps a risky experiment out of your working tree. The branch and the files live somewhere else, and removing the worktree removes both.
How it works
01Claude Code creates the worktree and moves the session into it
By default under
.claude/worktrees/<name>/, on a new branch, branched from the repository’s default branch on the remote. Setworktree.baseRefto"head"to branch from your current localHEADinstead.02Gitignored files listed in .worktreeinclude are copied in
A worktree is a fresh checkout, so
.envand friends are missing. A.worktreeincludefile at the project root, in gitignore syntax, names the gitignored files to copy into every worktree Claude Code creates with git.03The isolation checks apply for the life of the session
File edits, command working directories, and git redirects that reach the main checkout are refused. Claude sees each refusal as a tool error naming the worktree.
04Some things are still shared
The repository’s
.gitdirectory — sogit commitworks, and the sandbox allows those writes. Project-scope plugins. And permission approvals: "Yes, don’t ask again" in a worktree saves to the main checkout’s.claude/settings.local.jsonand survives the worktree’s removal.05Resuming returns the session to its worktree
Interactive resumes,
--continueand--resumeunder-p, and the Agent SDK all re-enter it, after Claude Code verifies the directory is still a separate checkout. If the directory is gone, the session resumes where you launched from and the binding is cleared.06Exit prompts you about the work in it
A clean unnamed worktree is removed automatically with its branch. A named one prompts. A worktree with changes, untracked files, or new commits always prompts to keep or remove. Non-interactive
-pruns have no exit prompt, so remove those yourself.
How to implement it
01Gitignore the worktree directory
Add
.claude/worktrees/to.gitignoreso worktree contents do not show up as untracked files in your main checkout.02List the gitignored files each worktree needs
Create
.worktreeincludeat the project root naming.env,.env.local, and any other untracked config. Only files that match and are also gitignored are copied.03Start each parallel session with its own name
Run
claude --worktree feature-authin one terminal andclaude --worktree fix-429in another. Reusing a name opens the existing worktree instead of creating a new one.04Set up the environment inside the worktree
A fresh checkout has no
node_modules. Install dependencies in the worktree directory, or ask Claude to do it as its first step.05Isolate the subagents that write
Add
isolation: worktreeto any subagent definition that edits files in parallel, and setworktree.baseRefto"head"if those agents must operate on your in-progress work.
Examples
# Terminal 1 — build the feature
claude --worktree feature-auth
# creates .claude/worktrees/feature-auth on branch worktree-feature-auth
# Terminal 2 — fix the bug at the same time
claude --worktree fix-429
# Branch a worktree from an existing pull request
claude --worktree "#1234" # quote it: the shell treats # as a comment
# See what exists and clean up by hand
git worktree list
git worktree remove .claude/worktrees/fix-429
git worktree remove --force .claude/worktrees/fix-429 # if it has changes
git worktree prune # drop stale metadata.env
.env.local
config/secrets.json
.tool-versions---
name: refactorer
description: Applies a mechanical refactor across many files, then runs the tests. Use when the same change must land in more than a handful of files.
isolation: worktree
tools: Read, Edit, Write, Grep, Glob, Bash
model: sonnet
---
Apply the requested refactor across every affected file in this worktree.
Work in this order:
1. Grep for every occurrence before changing anything, and report the count.
2. Apply the change file by file. Do not reformat lines you did not need to touch.
3. Run the test suite. If it fails, fix the refactor, not the test.
4. Commit on this worktree's branch with a message naming the refactor.
Report the branch name, the file count, and the test result. If the tests do
not pass after two attempts, stop and report what is failing.Use it when
- Running a feature build and a hotfix at the same time without stashing or switching branches.
- Letting several subagents apply the same mechanical refactor to different parts of a codebase in parallel.
- Trying a risky approach in a checkout you can delete, while the main tree stays untouched.
- Reviewing a pull request locally with
claude --worktree "#1234"while your own branch stays checked out. - Giving a background session its own checkout so its edits never land in the tree you are looking at.
Avoid it when
- The work is sequential. One session on one branch has no coordination cost, no duplicated dependency install, and no merge at the end.
- Installing dependencies is slow or heavy. Every worktree is a fresh checkout, so a large
node_modulesor a build cache is paid again per tree. - The parallel tasks touch the same files anyway. Isolation prevents the collision; it does not resolve the merge conflict you get instead.
- You are not in a git repository. Worktrees require git — other version control systems need
WorktreeCreateandWorktreeRemovehooks to replace the git logic.
Common mistakes
SYMPTOMThe build fails immediately in a new worktree because
.envis missing.FIXA worktree is a fresh checkout and gitignored files are not carried over. Add a
.worktreeincludefile naming them, and install dependencies inside the worktree.SYMPTOMClaude refuses to run a command in a worktree session with an error about the main checkout.
FIXThat is the isolation check. The command’s working directory or a git redirect resolved into the main checkout. Run it against the worktree path instead.
SYMPTOMA resumed session lands outside its worktree and edits the main tree.
FIXResume from the main checkout, not from inside the worktree — Claude Code declines to vouch for a worktree when you launch from within it. Read the notice: it names which refusal applied.
SYMPTOMA
-prun leaves worktrees behind that pile up on disk.FIXNon-interactive runs have no exit prompt, so nothing cleans up. Remove them with
git worktree remove, and remember the periodic sweep only covers subagent and background-session worktrees.SYMPTOMA subagent with
isolation: worktreedoes not see your uncommitted work.FIXSubagent worktrees branch from the repository’s default branch by default. Set
"worktree": {"baseRef": "head"}in settings to branch from your currentHEADinstead.
Best practices
- Add
.claude/worktrees/to.gitignoreand a.worktreeincludefile to the project root on day one. - Name worktrees after the task so
git worktree listreads like a work queue. - Give each parallel session a distinct part of the codebase, so isolation prevents collisions rather than deferring them.
- Use
isolation: worktreeon every subagent definition that writes files. - Set
worktree.baseRefto"head"when the isolated work must build on your in-progress commits. - Remove worktrees when you are done:
git worktree remove <path>, adding--forcewhen it holds changes you have decided to discard.
Try it in five minutes
Run two isolated sessions and watch the isolation check fire.
- 1.In a git repository, add
.claude/worktrees/to.gitignoreand commit. - 2.Run
claude --worktree experiment-aand confirm withpwdthat the session is inside.claude/worktrees/experiment-a. - 3.Ask Claude to create a file in the worktree, then ask it to edit a file in the main checkout by absolute path. The second request is refused.
- 4.In another terminal, run
git worktree listand see both checkouts sharing one repository. - 5.Exit the session, choose to remove the worktree, and confirm with
git worktree listthat it is gone.
Related concepts
Verified against code.claude.com/docs/en/worktrees on 2026-08-09. See content/SOURCES.md for the full table.
← / → MOVE BETWEEN CONCEPTS