11 / 20Workflow6 MIN READ

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.

Two worktree branches advancing in parallelA shared repository history on the left splits into two branch lanes that advance independently, each with its own commits, while both stay connected to the same git directory..gitsharedhistoryworktree-feature-authworktree-fix-429separate files · separate branch · one repository

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

  1. 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. Set worktree.baseRef to "head" to branch from your current local HEAD instead.

  2. 02Gitignored files listed in .worktreeinclude are copied in

    A worktree is a fresh checkout, so .env and friends are missing. A .worktreeinclude file at the project root, in gitignore syntax, names the gitignored files to copy into every worktree Claude Code creates with git.

  3. 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.

  4. 04Some things are still shared

    The repository’s .git directory — so git commit works, 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.json and survives the worktree’s removal.

  5. 05Resuming returns the session to its worktree

    Interactive resumes, --continue and --resume under -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.

  6. 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 -p runs have no exit prompt, so remove those yourself.

How to implement it

  1. 01Gitignore the worktree directory

    Add .claude/worktrees/ to .gitignore so worktree contents do not show up as untracked files in your main checkout.

  2. 02List the gitignored files each worktree needs

    Create .worktreeinclude at the project root naming .env, .env.local, and any other untracked config. Only files that match and are also gitignored are copied.

  3. 03Start each parallel session with its own name

    Run claude --worktree feature-auth in one terminal and claude --worktree fix-429 in another. Reusing a name opens the existing worktree instead of creating a new one.

  4. 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.

  5. 05Isolate the subagents that write

    Add isolation: worktree to any subagent definition that edits files in parallel, and set worktree.baseRef to "head" if those agents must operate on your in-progress work.

Examples

Parallel sessionsbash
# 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
Two isolated sessions, then cleanup. Claude Code manages the worktrees it creates; `git worktree` manages the rest.
.worktreeincludebash
.env
.env.local
config/secrets.json
.tool-versions
Gitignore syntax. Only files that match a pattern and are also gitignored get copied.
.claude/agents/refactorer.mdmarkdown
---
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.
A subagent that always gets its own checkout, so several can run at once without colliding.

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_modules or 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 WorktreeCreate and WorktreeRemove hooks to replace the git logic.

Common mistakes

  • SYMPTOMThe build fails immediately in a new worktree because .env is missing.

    FIXA worktree is a fresh checkout and gitignored files are not carried over. Add a .worktreeinclude file 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 -p run 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: worktree does 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 current HEAD instead.

Best practices

  • Add .claude/worktrees/ to .gitignore and a .worktreeinclude file to the project root on day one.
  • Name worktrees after the task so git worktree list reads like a work queue.
  • Give each parallel session a distinct part of the codebase, so isolation prevents collisions rather than deferring them.
  • Use isolation: worktree on every subagent definition that writes files.
  • Set worktree.baseRef to "head" when the isolated work must build on your in-progress commits.
  • Remove worktrees when you are done: git worktree remove <path>, adding --force when it holds changes you have decided to discard.

Try it in five minutes

Run two isolated sessions and watch the isolation check fire.

  1. 1.In a git repository, add .claude/worktrees/ to .gitignore and commit.
  2. 2.Run claude --worktree experiment-a and confirm with pwd that the session is inside .claude/worktrees/experiment-a.
  3. 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. 4.In another terminal, run git worktree list and see both checkouts sharing one repository.
  5. 5.Exit the session, choose to remove the worktree, and confirm with git worktree list that it is gone.

Verified against code.claude.com/docs/en/worktrees on 2026-08-09. See content/SOURCES.md for the full table.

← / → MOVE BETWEEN CONCEPTS