# Git worktree in Claude Code: parallel sessions

> How to use --worktree, .worktreeinclude, worktree.baseRef, and subagent isolation. Differences from branches, cleaning up worktrees, and common mistakes.

Source: https://ailoot.ai/blog/en/claude-code-git-worktree/
Canonical: https://ailoot.ai/blog/en/claude-code-git-worktree/
Language: en
Publisher: Ailoot (https://ailoot.ai/)
Translation: guide-045
Revision: sha256-e6a77386f3bc3e11050970db4ff014c6d4faa8b96f4107e362646cb44a2dffce




[Practical information about working with Ailoot is in the documentation](https://ailoot.ai/docs/).

## What is a git worktree in Claude Code

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

A Git worktree is a separate working directory for another branch of the same repository. The command `claude --worktree <name>` automatically creates a worktree in `.claude/worktrees/<name>/` and starts Claude Code in it. Two terminals → two sessions → different files on disk, zero interference. Available out of the box in Claude Code v2.0+, configurable through `.worktreeinclude` for secrets and `worktree.baseRef` for choosing the base branch.

</div>

Launching several agents in parallel in the same folder is the basic pain point of vibe-coding at 2026 speed. AI agents write code faster than a person can keep track of who is touching what. Without file isolation, launching two parallel Claude Code sessions in one directory ends with one session overwriting the other's work.

Git worktree solves this at the filesystem level. You have one main directory where you work. The command `claude --worktree feature-auth` creates the folder `.claude/worktrees/feature-auth/` on a separate branch and starts Claude Code there. The files are isolated. Changes in one session are not visible to the other until you explicitly merge them.

The official Anthropic documentation puts it this way:

<figure>
<blockquote>
<p>Running each Claude Code session in its own worktree means edits in one session never affect files in another. You can build a feature in one terminal and fix a bug in another.</p>
</blockquote>
<figcaption>— Anthropic Docs, https://code.claude.com/docs/en/worktrees</figcaption>
</figure>

A self-check hint: if you've ever gotten a commit where half the files were someone else's work, you need a worktree.

## How git worktree differs from a regular branch

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

A regular `git checkout` switches the working copy in the same folder—the old files disappear from disk until you return to the branch. `git worktree add` creates a **second folder** for another branch alongside the first. Both branches live on disk at the same time; you move between them with a simple `cd`. Under the hood, there is one `.git` repository, with shared history and a shared remote. Just several working copies.

</div>

The standard Git flow: you're on the `main` branch and run `git checkout feature-x`—Git overwrites the working copy's files. A running `npm run dev` breaks because `package.json` changed underneath it. You stash your uncommitted changes and wait for the IDE to reindex. You switch back and everything gets overwritten again, so you have to stash and pop again.

Git worktree gives you another option: instead of switching **one** folder between branches, you create a **second** folder for another branch. The command `git worktree add ../project-feature-x feature-x` creates the directory `../project-feature-x/` with the files from branch `feature-x`. Your `main` stays in the original folder, and the dev server keeps running.

| Parameter | `git checkout` branch | `git worktree add` |
|----|----|----|
| Working copy files | Overwritten | Appear in a new folder |
| Parallel work on two branches | No | Yes |
| Uncommitted changes | Need `git stash` | Nothing to do |
| Switching speed | Depends on the size of the delta | Just `cd` |
| Disk space | 1× | N× (one copy of the files per branch) |

Previously, worktree mode in Claude Code had to be set up manually: `git worktree add`, then `cd`, then `claude`—and repeat in every terminal. The `--worktree` flag (also `-w`) does all three in one command.

## Launch the first parallel session: the `--worktree` flag

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

The command `claude --worktree feature-auth` creates a worktree in `.claude/worktrees/feature-auth/`, creates the `worktree-feature-auth` branch from `origin/HEAD`, and starts Claude Code right there. No manual `git worktree add` or `cd`. In the neighboring terminal, repeat with a different name to get two independent sessions. If you omit the name (`claude --worktree`), Claude generates a random one like `bright-running-fox`.

</div>

Minimal example. Open the first terminal at the project root:

```bash
claude --worktree feature-auth
```

Claude Code does three things:

1. Creates `.claude/worktrees/feature-auth/` with a snapshot of `origin/HEAD` (usually your default branch).
2. Creates a new `worktree-feature-auth` branch.
3. Starts the session in this folder.

Open a second terminal in the same repository root folder:

```bash
claude --worktree bugfix-123
```

Done. Two Claude Code sessions, different files on disk, different Git branches. If you write authentication in the first and fix a failing test in the second, they physically can't get in each other's way.

If you don't want to type a name, Claude will come up with one:

```bash
claude --worktree
# → creates something like .claude/worktrees/bright-running-fox/
```

A tip for Git beginners: add `.claude/worktrees/` to `.gitignore`. Otherwise, when you run `git status` in the main folder, you'll see the contents of all worktrees as untracked files:

```
# .gitignore
.claude/worktrees/
```

Pitfall to avoid: before the first `--worktree` launch in a new directory, enter it with a regular `claude` (without the flag) and accept the workspace trust dialog. If you don't, the flag fails with a “trust not accepted” error—including if you combine it with `-p` for headless mode.

## Where worktrees live and how to find them

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

By default, all worktrees live in `.claude/worktrees/<name>/` next to your repository root. To see the list, run `git worktree list`. To enter a worktree manually, use `cd .claude/worktrees/feature-auth`. To switch inside a Claude session, ask it to “switch to another worktree”; it uses the built-in EnterWorktree tool. The old worktree stays untouched on disk.

</div>

The default location is fixed: `.claude/worktrees/<value>/` at the repository root. If your project is in `~/dev/my-app/`, the `feature-auth` worktree will be in `~/dev/my-app/.claude/worktrees/feature-auth/`.

For nonstandard layouts (for example, if you want the worktree outside the repository), there is the `WorktreeCreate` hook—more on that below in the section about SVN and Mercurial.

Within one Claude session, you can switch to another existing worktree. Just say in the chat: “switch to `.claude/worktrees/bugfix-123`,” and Claude will call the `EnterWorktree` tool. The current folder will remain untouched—you can return the same way.

The standard Git command shows a list of all worktrees, including the main one and those created manually:

```bash
git worktree list
```

The output will look like this:

```
/home/user/dev/my-app                  abc1234 [main]
/home/user/dev/my-app/.claude/worktrees/feature-auth  def5678 [worktree-feature-auth]
/home/user/dev/my-app/.claude/worktrees/bugfix-123    9876fed [worktree-bugfix-123]
```





## Copying `.env` and secrets: the `.worktreeinclude` file

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

A worktree is a fresh checkout. Files from `.gitignore` (`.env`, `.env.local`, local configs) are absent from the new folder. Without them, `npm run dev` or `prisma db push` won't run. The `.worktreeinclude` file at the project root uses `.gitignore` syntax and tells Claude Code what to copy automatically into every new worktree. It is picked up for `--worktree`, subagent worktrees, and desktop app sessions.

</div>

When `--worktree` creates a new folder, it gets only what is committed to Git. `.env` with API keys and `.env.local` with local configuration are in `.gitignore`, so they aren't in the worktree. And the very first `npm run dev` fails with “MISSING DATABASE_URL.”

The homemade solution is to copy `.env` manually after every `--worktree`. It works once, then gets forgotten. Anthropic's solution is a `.worktreeinclude` file at the project root listing the Git-ignored files to copy automatically into every new worktree.

Create a `.worktreeinclude` file at the repository root:

```
.env
.env.local
config/secrets.json
```

The syntax is the same as `.gitignore`. You can use glob patterns:

```
.env*
*.local
config/*.json
.vscode/settings.json
```

Anthropic gives a clear rule to prevent accidents:

<figure>
<blockquote>
<p>The file uses gitignore syntax. Only files matching the pattern that are also gitignored are copied. Git-tracked files are never duplicated.</p>
</blockquote>
<figcaption>— Anthropic Docs, https://code.claude.com/docs/en/worktrees</figcaption>
</figure>

In other words, you can't accidentally copy `package.json` through `.worktreeinclude`—it isn't in `.gitignore`. It's safe to put any patterns there.

The same `.worktreeinclude` works in three modes: manual `--worktree`, automatic worktrees for subagents (see below), and sessions from the Claude desktop app.

## Worktree from a pull request for code review

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

The command `claude --worktree "#1234"` fetches pull request \#1234 from origin and creates a worktree in `.claude/worktrees/pr-1234/` with the PR branch. You can pass the full URL—`claude --worktree https://github.com/OWNER/REPO/pull/1234`. Useful for code review: open the PR in its own folder, and Claude can run tests, read logs, and write a comment while the main repository remains untouched.

</div>

A standard code review scenario: a colleague sent a PR; you need to inspect the code, run tests, and leave a comment. With a regular `git checkout pull/1234/head`, you switch the working copy again and break your active session.

With the `--worktree` flag, this takes one command:

```bash
claude --worktree "#1234"
```

What happens: Claude Code runs `git fetch origin pull/1234/head`, creates a worktree in `.claude/worktrees/pr-1234/`, and checks out the PR branch. The session starts. You can immediately ask it to “read the diff, run the tests, and find logical errors”—while Claude works, your main session on `main` keeps running.

The alternative syntax is the full pull request URL:

```bash
claude --worktree https://github.com/OWNER/REPO/pull/1234
```

Use in a real project: pairing `claude --worktree "#N"` with your own code-reviewer subagent gives you an automatic review in a minute or two. Launch it in the background, continue your work in the main window, and return to the result through `claude agents`.

## Base branch: `worktree.baseRef` for `fresh` or `head`

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

By default, a worktree branches from `origin/HEAD`—the latest synced commit from the remote. This is a safe, “clean” start. If you want the worktree to include local unpushed commits, set `worktree.baseRef: "head"` in settings. HEAD identifies a commit; uncommitted tracked edits remain in the original working copy and require a separate, explicit transfer. Useful when a subagent needs to work on top of your current feature without switching to main. It accepts only `fresh` or `head`; arbitrary refs aren't supported.

</div>

The default setting is this: every new worktree starts from `origin/HEAD`. The advantage is a clean start that is guaranteed to match what CI will see. The drawback is that if you have uncommitted changes or several local commits beyond the remote on your current branch, they won't be included in the new worktree.

To start a worktree from your current local HEAD commit, add this to `.claude/settings.json` (or global settings):

```json
{
  "worktree": {
    "baseRef": "head"
  }
}
```

Now `claude --worktree experimental-feature` starts from the current local `HEAD`. This is useful when your feature already has local commits that have not been pushed. It does not include tracked edits that are still uncommitted. If the subagent needs those edits, preserve and transfer the required changes explicitly, then inspect the destination diff; do not confuse that transfer with `.worktreeinclude`, which handles ignored local files.

The setting accepts exactly two values: `"fresh"` (= `origin/HEAD`) and `"head"` (= local HEAD). No arbitrary refs like `"feature-branch"` or a commit hash—this is a deliberate restriction to prevent a combinatorial explosion of options.

## Isolate subagents automatically: `isolation: worktree`

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

A subagent in Claude Code is a specialized agent that performs one task (code review, refactoring, research). If you launch several subagents in parallel from one session, they work in the same folder by default and can overwrite each other's files. Add `isolation: worktree` to the subagent frontmatter to give each one a temporary worktree, which is cleanly removed at the end if it hasn't committed anything.

</div>



When you tell Claude “launch three subagents: one reads the database, the second looks at the API, and the third checks the tests,” all three work in your working copy by default. If even two of them write to the same file at the same time, there's a conflict. The solution is to give each one its own worktree automatically.

Method 1: ask verbally. Write to Claude in the conversation:

```
Use worktrees for your agents.
```

Claude will apply isolation to all subsequent subagents in this session.

Method 2: set it explicitly in the subagent itself. In the subagent file (for example, `.claude/agents/code-reviewer.md`), add a field to the frontmatter:

```yaml
---
name: code-reviewer
description: Reads the diff and writes code review comments
isolation: worktree
---

You're a meticulous reviewer. Read the diff and look for logic errors...
```

Now every launch of this subagent gets a temporary worktree in `.claude/worktrees/`. If the subagent didn't write anything, the folder is deleted automatically when it finishes. If there are uncommitted changes, Claude will ask whether to keep or remove them.

The base branch for subagent worktrees is the same as for `--worktree`: by default, `origin/HEAD`; with `worktree.baseRef: head`, local `HEAD`.

## Decision matrix: worktree, `/bg`, subagent, or Agent View

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

Four Claude Code mechanisms that are often confused. Worktree is **file isolation** (disk). `/bg` is a **background session** (context and tokens). Subagent is a **specialized one-off agent** (prompt and tools). Agent View is a **dashboard for all sessions** (UI). They can be combined: `/bg` creates a worktree automatically, a subagent with `isolation: worktree` starts in a temporary worktree, and Agent View shows all three as rows in one list.

</div>

| Tool | What it isolates | When to use it |
|----|----|----|
| `claude --worktree <name>` | Files (separate folder + branch) | You want to manually keep N sessions running in parallel in different terminals |
| `/bg` (or `Ctrl+B`) | Context and time | A long task when you don't want to block the current window. A worktree is created under the hood |
| Subagent with `isolation: worktree` | Files within one session | One prompt assigns work to N agents, and you need protection from them overwriting one another |
| `claude agents` (Agent View) | Nothing, it's a UI | You want to see all running / paused / completed sessions in one dashboard |
| `/goal` | Autonomy management | You want Claude to work until a condition is met without prompts from you between turns |

Typical combinations:

- **“2 features in parallel, manually”** — two terminals, each running `claude --worktree`. The simplest case.
- **“Launch an overnight refactor; I'll close the app”** — `/bg` + `/goal` with a completion condition. The session runs independently of your window.
- **“One prompt, three parallel investigations”** — three subagents with `isolation: worktree`. Each in its own sandbox.
- **“What's running right now?”** — `claude agents`. A dashboard of all sessions with “running,” “blocked,” and “done” filters.

## 5 pitfalls when working with worktrees

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

The most common problems: forgetting `.worktreeinclude` and having the environment not work; confusing a worktree with a regular branch and losing uncommitted changes; keeping 5+ parallel sessions and forgetting what is where; failing to configure `cleanupPeriodDays` so dead folders pile up; and forgetting the trust dialog in a new directory, causing `--worktree` to fail with an error.

</div>

**1. Launched a worktree, `.env` is missing, nothing works.** The most common problem. A worktree is a fresh checkout with no Git-ignored files. The solution is to add a `.worktreeinclude` file with `.env*` and the necessary local configs as soon as you set up worktree mode. Check that the file is at the repository root, not in `.claude/`.

**2. You want to switch to the main branch, run `cd` to the root, and lose your uncommitted changes in the worktree.** The root folder and worktree are two **different** working copies. You went back with `cd`; the changes in the worktree stayed in place—they didn't go anywhere. But if you got mixed up and ran `git stash` in the main folder, thinking you were in the worktree, the stash will be created on the main branch, not the one you expected.

**3. Launched 5 parallel sessions and can't remember what each one is doing.** Anthropic's documentation explicitly warns that most developers can't cognitively handle more than 2–3 sessions. A sign of overload is opening Agent View and not being able to immediately say what each agent is doing. Limit yourself to two concurrent sessions. If the task requires more, it should be orchestrated through `/goal` + subagents, not manually.

**4. Worktrees from `-p` (headless) aren't cleaned up automatically.** The command `claude --worktree feature-x -p "do thing"` doesn't show an interactive exit prompt, so there's no point when Claude asks “remove the worktree?” These worktrees accumulate. Clean them manually: `git worktree remove .claude/worktrees/feature-x`. Or use a cron script that removes anything older than 7 days.

**5. Trust dialog in a new folder.** If you open the repository for the first time and immediately run `claude --worktree`, the command will fail. Run `claude` without flags, accept workspace trust, and exit—then `--worktree` will work. This is intentional so Claude doesn't get access to someone else's project without the user's consent.

## Cleanup: what gets deleted automatically

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

A worktree from `--worktree` with no changes (no commits, no untracked files, no uncommitted changes) is automatically removed when you exit. With changes, Claude will ask. Worktrees from subagents and `/bg` are automatically removed by the `cleanupPeriodDays` timeout in settings if they're clean. Worktrees from `-p` aren't cleaned up at all—remove them manually with `git worktree remove`.

</div>

The cleanup logic depends on what you've done in the worktree and how you started the session. Anthropic's documentation lists three scenarios:

<figure>
<blockquote>
<p>If the worktree has no uncommitted changes, untracked files, or new commits, the worktree and its branch are automatically removed when you exit the session. If the session has a name, Claude asks instead of removing it so you can keep the worktree for later.</p>
</blockquote>
<figcaption>— Anthropic Docs, https://code.claude.com/docs/en/worktrees</figcaption>
</figure>

Scenario 1: you entered, did nothing, and exited—the worktree was removed.

Scenario 2: you did some work and didn't commit it—Claude will ask “keep or remove?” when you exit. “Keep” saves the folder and branch for later. “Remove” deletes the directory **together with** uncommitted changes and new commits. This is destructive—don't click “remove” out of habit.

Scenario 3: you launched with `-p` (headless), and the command finished and exited. The worktree remains. Clean it manually:

```bash
git worktree remove .claude/worktrees/feature-x
```

Additionally, worktrees from subagents and `/bg` sessions are automatically removed by background cleanup if they are older than `cleanupPeriodDays` days (a setting, usually 30 days by default) **and** have no unsaved work. Worktrees from `--worktree` aren't touched by automatic cleanup—they're your responsibility.

## Alternatives for SVN, Perforce, and Mercurial: the `WorktreeCreate` hook

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

Worktree mode uses `git worktree` by default. For SVN, Perforce, Mercurial, and other VCSs, you can connect your own mechanism through the `WorktreeCreate` and `WorktreeRemove` hooks in Claude Code settings. The hook receives the name on stdin, must print the path to the created directory, and exit with code 0. When you use your own hook, `.worktreeinclude` isn't processed—you must copy local files yourself within the hook.

</div>

If the repository uses Subversion or Mercurial, the `--worktree` flag won't work directly. Anthropic provides an extension point through two hooks: `WorktreeCreate` (creates an isolated copy) and `WorktreeRemove` (removes it).

Example SVN hook from the official documentation:

```json
{
  "hooks": {
    "WorktreeCreate": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'NAME=$(jq -r .name); DIR=\"$HOME/.claude/worktrees/$NAME\"; svn checkout https://svn.example.com/repo/trunk \"$DIR\" >&2 && echo \"$DIR\"'"
          }
        ]
      }
    ]
  }
}
```

The hook reads the worktree name from stdin (`{ "name": "feature-auth" }`), runs `svn checkout` into a precomputed directory, and prints the path to stdout—Claude Code uses it as the working directory for the new session.

An important caveat: when using your own hook, `.worktreeinclude` isn't used. If you need `.env` or other Git-ignored files in the new folder, copy them within the hook script itself.

## What's next: three adjacent parallelism mechanisms

<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Section takeaway">

Key takeaway

Worktree provides file isolation. `/bg` provides context and token isolation. Subagent provides task and tool isolation. `/goal` provides autonomy until a condition is met. Each solves one problem on its own. Together they make it possible to keep 3–5 parallel tasks going without cognitive collapse. Next, it makes sense to explore the related guides on autonomous mode, custom subagents, and dynamic workflows through the links below.

</div>

Worktree gives you file isolation. `/bg` gives you context isolation. Subagents give you task isolation. Each mechanism solves one problem on its own. Together, they provide a way to work on three to five parallel tasks without cognitive collapse. This is the skill set behind advanced vibe-coding in 2026.

This topic naturally continues into three related subjects: [how to set up an autonomous agent using `/goal` and Agent View](https://ailoot.ai/blog/en/claude-code-goal-agent-view/), [how to build your own subagents for your tasks](https://ailoot.ai/blog/en/claude-code-subagents/), and [how to launch hundreds of agents through Dynamic Workflows](https://ailoot.ai/blog/en/claude-code-dynamic-workflows/).



<div class="section" role="doc-bibliography" aria-label="Sources">

### Sources

- [Run parallel sessions with worktrees - Claude Code Docs](https://code.claude.com/docs/en/worktrees)
- [Create custom subagents - Claude Code Docs](https://code.claude.com/docs/en/sub-agents)
- [Claude Code Changelog (May-June 2026)](https://code.claude.com/docs/en/changelog)
- [Run agents in parallel - Claude Code Docs](https://code.claude.com/docs/en/agents)
- [Agent View - Claude Code Docs](https://code.claude.com/docs/en/agent-view)
- [git worktree man page](https://git-scm.com/docs/git-worktree)






</div>





[Open Ailoot](https://ailoot.ai/).

## Questions about Git worktree in Claude Code: parallel sessions

### Does baseRef head copy uncommitted changes into a new worktree?

No. It starts from the current local HEAD commit, including local commits absent from the remote. Tracked edits that have not been committed remain in the original working copy; transfer any required WIP explicitly and inspect the new worktree.

### Why is my .env missing in a new worktree?

A worktree is a fresh checkout, so Git-ignored local files are absent. Claude Code’s `.worktreeinclude` lists ignored files to copy; a custom WorktreeCreate hook must handle such copying itself. Include only the files the task actually needs.


## Ailoot · The company and its project portfolio

Ailoot combines established operating experience, a large client base, stable service and ongoing KPI control.

The company and its project portfolio: millions of customers; monthly sales in the billions.

Ailoot brings that operating experience to API access for AI features in customer products, agents, applications and automations.
