Claude Code With Git Worktrees: Parallel Sessions Without Collisions

Start Claude Code with --worktree and each session gets its own checkout and branch, so two sessions never edit the same files. How the flag works, what a worktree shares with your main checkout, how isolation is enforced, and how to clean up afterward.

7 min read

To run Claude Code in a git worktree, start it with claude --worktree <name> (or -w <name>). Claude Code creates a separate checkout under .claude/worktrees/<name>/ on a new branch called worktree-<name>, and the session works there instead of in your main checkout. Start a second session with a different name in another terminal and the two can edit, build and test at the same time without touching each other’s files. When you exit, Claude Code removes a clean worktree or asks whether to keep one that has work in it. Worktrees solve the file problem only: two sessions can still pick the same job, and their branches still meet at merge time.

Start a session in a worktree

Anthropic’s worktrees guide (opens in a new tab) covers the flag in full. The short version:

Terminal
# Terminal 1: a feature
claude --worktree feature-auth

# Terminal 2: a bug fix, isolated from the first
claude -w fix-cart-total

# No name: Claude Code generates one, such as bright-running-fox
claude --worktree
  • The worktree lives at .claude/worktrees/<name>/ in your repository root. Add .claude/worktrees/ to .gitignore so its contents do not show up as untracked files in your main checkout.
  • Interactive runs need workspace trust. If you have never run Claude in that repository, run claude there once and accept the trust dialog, or --worktree exits with an error asking you to.
  • Passing a name whose directory already exists reopens that worktree instead of creating a new one.
  • Add --tmux to open the worktree session in its own tmux session, or in iTerm2 panes where available. It requires --worktree.

What a worktree is, and what it shares

A worktree is a git feature, not a Claude Code one. The git worktree documentation (opens in a new tab) describes it as an extra working tree attached to the same repository: its own files and its own branch, sharing the history and the remote. A commit made in the worktree is in the repository at once; nothing needs copying back.

Claude Code documents what a worktree session shares with your main checkout:

  • The .git directory. Commits, branches and stashes all land in the one repository, and commands such as git commit work inside a worktree even with the sandbox on.
  • Permission approvals. Choosing “Yes, and don’t ask again” for a command in a worktree saves the rule to the main checkout’s .claude/settings.local.json, so it applies in every worktree and survives removal. On Windows the rule stays with that worktree.
  • Project-scope plugins, and untracked skills, agents and commands. If the worktree has no .claude/skills folder of its own, for example because yours is gitignored, the main checkout’s copy loads.

What it does not share: anything gitignored. A worktree is a fresh checkout, so there is no node_modules, no build output and no .env. Install dependencies in each one, and list the gitignored files it needs in a .worktreeinclude file at the project root. It uses .gitignore syntax, and only files that match a pattern and are also gitignored are copied.

.worktreeinclude
.env
.env.local
config/secrets.json

Choose where the branch starts

By default a new worktree branches from your repository’s default branch on the remote, usually main, so it starts clean even if your main checkout is halfway through something else. Claude Code fetches the default branch first if it has not been fetched in the last 24 hours. If the session should build on your unpushed work instead, set worktree.baseRef to "head" in settings:

.claude/settings.json
{
  "worktree": {
    "baseRef": "head"
  }
}

The setting takes only "fresh" or "head", not a branch name. To start from a pull request, pass its number in quotes, claude --worktree "#1234", or its URL; Claude Code fetches that change from origin and creates .claude/worktrees/pr-1234. To start from any other existing branch, create the worktree yourself with git worktree add ../project-bugfix fix-issue-456, change into it and run claude.

How Claude Code keeps a session inside its worktree

A worktree is only useful if the session stays in it. While a session is isolated, Claude Code blocks four kinds of tool call: file edits aimed at the main checkout, shell commands whose working directory is the main checkout, git commands redirected into it (git -C, --git-dir, GIT_DIR or a cd first), and commands too dynamic to check. Claude sees each refusal as a tool error explaining how to rewrite the command. The same checks apply to every subagent the session spawns.

One trap for hooks (opens in a new tab): $CLAUDE_PROJECT_DIR keeps pointing at the directory where the session started, so a hook script referenced through it runs from the main checkout. The cwd field in the hook’s input JSON is the one that follows Claude into the worktree. Read that when a hook needs the worktree path.

Other ways in: mid-session, VS Code, desktop and subagents

  • Mid-session. Ask Claude to “work in a worktree” and it creates one with its EnterWorktree tool. Entering a path outside .claude/worktrees/ asks for your approval first, in every mode except bypassPermissions.
  • VS Code. The extension’s documentation points to the same worktree guide rather than a separate button, so run claude --worktree <name> in the integrated terminal, or ask for a worktree in the chat.
  • Desktop app. The desktop documentation (opens in a new tab) describes a worktree option next to the branch name when you start a session. You can move the worktree location and add a branch prefix in settings, and archive a session to remove its worktree.
  • Subagents. Ask Claude to “use worktrees for your agents”, or add isolation: worktree to a custom subagent’s frontmatter so it always gets a temporary worktree of its own.
.claude/agents/refactorer.md
---
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.

Cleaning up

When you exit an interactive worktree session, Claude Code checks for work that removal would delete: changed or untracked files, uncommitted work in submodules, and new commits.

  • Clean worktree, unnamed session: removed with its branch automatically. A named session asks first.
  • Work in it: you choose. Keep preserves the directory and branch, and Claude Code prints the claude --worktree <name> --resume command to come back. Remove deletes the directory, the branch and the work in them.
  • State it cannot verify: it asks rather than removing anything.
  • Headless runs with -p get no exit prompt and no cleanup. Remove those worktrees yourself.
  • Worktrees made for subagents and background sessions are swept once they are older than your cleanupPeriodDays setting, unless they still hold work.
Terminal: tidy up by hand
git worktree list
git worktree remove .claude/worktrees/feature-auth
# locked by a session that was killed? unlock it first
git worktree unlock .claude/worktrees/feature-auth
# forget worktrees whose folders you already deleted
git worktree prune

Add --force to git worktree remove only when you are sure the uncommitted changes can go. Removing a worktree does not delete a branch you pushed; delete that on the remote once it has merged.

When a worktree is the wrong tool

  • One session at a time. If only one Claude session touches the repository, a worktree adds a setup step and a folder to clean up for no benefit.
  • Work that touches the same files. Worktrees defer the conflict to merge time rather than remove it. Split the work so each session owns different files.
  • Heavy setup. Each worktree needs its own dependencies and build, so five worktrees can mean five installs and five dev servers competing for ports and disk.
  • Coordinated teams. Agent teams do not put teammates in worktrees; the documentation says to partition files instead. The differences are in Claude Code subagents vs agent teams.

Name the worktree after the task

The most useful habit costs nothing: name each worktree after the task it is for. claude --worktree bug-042 "Work on BUG-042" gives you a branch called worktree-bug-042, a folder with the same name, and a session that already knows its job. Anybody reading the branch list, the pull request or the board can match one to the other.

On a fenbs board the ref is already there, FET-, ENH- or BUG- plus a number, so the worktree name writes itself. Have each session move its task to In Progress when it starts and comment the worktree name, then comment the commit and how it was tested before the task moves to Completed. fenbs does not lock a task or assign it to a session, so the comment is what tells two sessions apart; the full claiming routine is in running Claude Code tasks in parallel. Every change a session makes shows in the task’s history as “Claude via” the person it connected as.

Related

Choosing branch rules for people and agents: git branching strategy for small teams. Connecting Claude Code to a board: Claude Code integration. A session routine that ends with the board updated: a task-tracking workflow for Claude Code.

Questions people ask.

How do I start Claude Code in a git worktree?

Run claude --worktree followed by a name, or the short form -w. Claude Code creates the worktree under .claude/worktrees in your repository root, on a new branch called worktree- plus the name, and starts the session there. Leave out the name and it generates one.

Where does Claude Code put its worktrees?

Under .claude/worktrees/<name>/ at the repository root by default. Add .claude/worktrees/ to your .gitignore. The desktop app lets you change the location in its settings, and a WorktreeCreate hook can replace worktree creation entirely.

Why is my .env file missing in the worktree?

A worktree is a fresh checkout, so gitignored files are not there. List them in a .worktreeinclude file at the project root, using .gitignore syntax, and Claude Code copies them into each new worktree it creates with git.

Does Claude Code delete the worktree when I exit?

A clean worktree from an unnamed session is removed automatically. If there are changes, untracked files or new commits, it asks whether to keep or remove it. Runs with -p never clean up, so remove those with git worktree remove.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.