# Claude Worktree Guide: Parallel Agents in Claude Code, Codex and Cursor

> Claude worktree setup for real projects: run Claude Code, Codex and Cursor agents in parallel git worktrees without colliding .env files, ports or databases.

Start two coding agents in one checkout and they share a scratchpad: agent A's half-written file is agent B's input, and whoever runs `git switch` last wins. A Claude worktree — Claude Code's `--worktree` flag, or any git worktree — fixes the files. It does not fix the `.env` that didn't come along, the two dev servers that both want port 3000, or the test runner that now finds your suite four times.

I ran every git command below in a scratch repo on git 2.55.0 and kept the output. Tool details are from Claude Code 2.1.287, Codex CLI 0.160.0, the Codex source at that tag, and Cursor's docs, all checked in October 2026.

**The short answer:** Give each agent its own git worktree: `claude --worktree <name>` in Claude Code, `codex --worktree` in the Codex CLI, `agent --worktree <name>` in Cursor's CLI, or the Worktree option in each desktop app. A worktree is a separate directory and branch over one shared `.git`, so agents can't overwrite each other's files. It doesn't copy gitignored files and doesn't separate ports, databases or Docker Compose projects. Copy `.env` with a `.worktreeinclude` file (Claude Code, Codex app) or `.cursor/worktrees.json` (Cursor), give each worktree its own `PORT`, `DATABASE_URL` and `COMPOSE_PROJECT_NAME`, and merge back locally — branches are shared, so no push is needed.

## Claude Code, Codex and Cursor Worktrees Compared

All three tools create worktrees for you now.

|                   | Claude Code                                     | Codex CLI                           | Codex app                                         | Cursor                                                    |
| ----------------- | ----------------------------------------------- | ----------------------------------- | ------------------------------------------------- | --------------------------------------------------------- |
| Start one         | `claude -w <name>`                              | `codex --worktree`, or `/worktree`  | Worktree, under the composer                      | Agents Window, `/worktree` in the IDE, `agent -w <name>`  |
| Where it lands    | `.claude/worktrees/<name>`, inside the repo     | `~/.codex/worktrees/<4 hex>/<repo>` | same root, changeable in Settings                 | under `~/.cursor/worktrees`, fixed (CLI: `<repo>/<name>`) |
| Starts from       | remote default branch (`baseRef: "fresh"`)      | your current HEAD commit            | the branch you pick, plus its uncommitted changes | not stated in the docs                                    |
| Branch            | new `worktree-<name>`                           | none (detached HEAD)                | none until "Create branch here"                   | not stated in the docs                                    |
| Gitignored files  | `.worktreeinclude`                              | not copied                          | `.worktreeinclude`                                | `setup-worktree` commands                                 |
| Automatic cleanup | on exit; subagent worktrees by a periodic sweep | never                               | keeps the newest 15                               | keeps the newest 25 per machine                           |

Sources: [Claude Code worktree docs](https://code.claude.com/docs/en/worktrees), [Codex worktree docs](https://learn.chatgpt.com/docs/environments/git-worktrees), the Codex CLI's [worktree crate at rust-v0.160.0](https://github.com/openai/codex/blob/rust-v0.160.0/codex-rs/worktree/src/lib.rs), [Cursor worktree docs](https://cursor.com/docs/configuration/worktrees) and [Cursor CLI docs](https://cursor.com/docs/cli/using).

Two rows bite people. Claude Code starts from the remote, so your unpushed commits aren't there; Codex starts from local HEAD with no branch, so you name one before you push. If you're still choosing the agent itself, [Codex vs Claude Code](/blog/codex-vs-claude-code) covers that; this guide is for running whichever you picked side by side.

## Claude Worktree Setup in Claude Code

`claude --worktree <name>` (short form `-w`) creates a Claude Code git worktree at `.claude/worktrees/<name>/` on a new branch `worktree-<name>` and starts the session there. Run it again with another name in a second terminal for the second agent. The flag arrived in Claude Code 2.1.49 per the [Claude Code changelog](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md), a version published on February 19, 2026 ([GitHub release v2.1.49](https://github.com/anthropics/claude-code/releases/tag/v2.1.49)).

```bash
claude --worktree feature-auth     # omit the name and Claude picks one, e.g. bright-running-fox
claude -w feature-auth --tmux      # same, in its own tmux session (iTerm2 panes when available)
claude --worktree "#1234"          # check out PR 1234 into .claude/worktrees/pr-1234
```

Expect three surprises on the first day.

**Your unpushed commits are missing.** The default `worktree.baseRef` is `"fresh"`: branch from the remote's default branch. To start from your local HEAD instead, put this in `settings.json` (the setting arrived in 2.1.133; it takes `fresh` or `head`, not a branch name):

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

**Your `.env` is missing.** Add a `.worktreeinclude` file at the repo root, in `.gitignore` syntax. Claude Code copies a file only when it matches a line here and is also gitignored, so tracked files are never duplicated:

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

**Your test runner finds every worktree.** `.claude/worktrees/` lives inside your repo. The docs tell you to gitignore it, which keeps it out of `git status` but not out of Vitest — Vitest doesn't read `.gitignore`. One project's [Vitest exclusion PR](https://github.com/joshpalay/Joshing-11/pull/1664) measured 2,888 test files collected against 374 real ones, with full runs dropping from 400–570 s to 94 s after the fix. Another project's [ESLint fix PR](https://github.com/turboladen/fewd/pull/105) traced 244 "No tsconfigRootDir was set" lint errors to ESLint loading each worktree's config. Exclude the folder explicitly:

```ts
// vitest.config.ts
import { configDefaults, defineConfig } from 'vitest/config';

export default defineConfig({
	test: { exclude: [...configDefaults.exclude, '**/.claude/worktrees/**'] }
});
```

In `eslint.config.js`, add `{ ignores: ['.claude/worktrees/**'] }`. Spread `configDefaults.exclude` rather than replacing it, or you drop Vitest's own `node_modules` exclusion.

On exit, Claude Code removes a clean, unnamed worktree on its own and asks about a named or dirty one; keeping it prints a `claude --worktree <name> --resume` command for coming back. Headless `claude -p --worktree` runs get no prompt: their worktrees stay on disk, locked, so you `git worktree unlock` before `git worktree remove`. Subagents can get the same isolation with `isolation: worktree` in their frontmatter. And if the repo uses Git LFS installed with `--local`, a fresh worktree holds pointer files until you run `git lfs pull` inside it.

Think twice before putting hand-made worktrees in `.claude/worktrees/`. [Claude Code issue #89199](https://github.com/anthropics/claude-code/issues/89199) reported in August 2026 that the retention sweep deleted two `git worktree add` checkouts there, about 13 GB of state. The changelog lists the fix in 2.1.246 ([GitHub release v2.1.246](https://github.com/anthropics/claude-code/releases/tag/v2.1.246), August 25, 2026), though the issue is still open. On 2.1.246 or later the sweep should leave your own worktrees alone; on anything older, keep them in another directory.

## Codex Worktree: the CLI Flag and the App

The Codex CLI got `--worktree` and the `/worktree` command as an experiment in 0.154.0 on September 9, 2026 ([release notes](https://github.com/openai/codex/releases/tag/rust-v0.154.0)) and switched them on by default in 0.156.0 on September 22 ([release notes](https://github.com/openai/codex/releases/tag/rust-v0.156.0)). In 0.160.0:

```bash
codex --worktree          # new managed worktree, session starts inside it
codex exec --worktree "fix the flaky date test"   # same for a headless run
```

From the [CLI's worktree source](https://github.com/openai/codex/blob/rust-v0.160.0/codex-rs/worktree/src/lib.rs), it runs `git worktree add --detach` at your current HEAD commit, so uncommitted edits stay behind and there's no branch. Create one inside the worktree with `git switch -c <name>` before you commit and push. Per the [worktree settings source](https://github.com/openai/codex/blob/rust-v0.160.0/codex-rs/worktree/src/settings.rs), the CLI shares the app's worktree root but never cleans up automatically. OpenAI's docs describe `.worktreeinclude` for the app's managed worktrees, and I found no copy step in the CLI's worktree code, so bring your `.env` yourself (the script below does).

In the app, pick **Worktree** under the composer and choose a starting branch. [Codex's docs](https://learn.chatgpt.com/docs/environments/git-worktrees) cover the rest:

- It carries the branch's uncommitted changes into the new checkout and works in detached HEAD. **Create branch here** turns it into a branch; **Hand off** moves the chat to your local checkout.
- It reads `.worktreeinclude`, skips symlinks, never overwrites an existing file, and copies an ignored `AGENTS.override.md` without being told.
- It keeps your 15 most recent managed worktrees, snapshots one before deleting it, and never deletes pinned, running or permanent ones. A permanent worktree (project three-dot menu) becomes its own project.
- The root moves under **Settings > Worktrees > Worktree root**.

One trap is specific to Codex. The checkout directory is named after your repo — `.../a1b2/myapp` — and Docker Compose names a project after its directory. That makes a Codex worktree the same Compose project as your main checkout; the per-worktree `.env` section below fixes it.

## Cursor Worktree Setup: Agents Window, /worktree and worktrees.json

Cursor creates worktrees from three places. The Agents Window does it natively. In the IDE you type `/worktree <task>`, `/best-of-n sonnet,gpt,composer <task>` to race models in separate worktrees, then `/apply-worktree` or `/delete-worktree`. The CLI takes `-w`:

```bash
agent --workspace ~/src/my-app --worktree auth-fix "fix the flaky auth test and open a PR"
```

Worktrees land under `~/.cursor/worktrees`; for CLI checkouts the docs give the layout `<repo>/<name>`. There's no setting to move it: a May 2026 reply in a [Cursor forum thread](https://forum.cursor.com/t/configure-worktree-location/149222) says the path is still hardcoded and suggests symlinking the directory elsewhere.

Setup runs from `.cursor/worktrees.json`, read from the worktree first and then the project root. Commands run in the new worktree, and `$ROOT_WORKTREE_PATH` points at your main checkout:

```json
{
	"setup-worktree": ["npm ci", "cp $ROOT_WORKTREE_PATH/.env .env", "npm run db:migrate"]
}
```

`setup-worktree-unix` and `setup-worktree-windows` override the generic key per OS, and either can name a script file instead of an array. When setup fails, open the Output panel and pick **Worktrees Setup**.

Cleanup is machine-wide: by default Cursor keeps the newest 25 worktrees across all workspaces (`cursor.worktreeMaxCount`), checking on the interval set by `cursor.worktreeCleanupIntervalHours` (the docs' example uses 6; no default is stated). Anything inside its root counts, including checkouts you add there with `git worktree add`, so keep your own elsewhere. Cursor's docs also advise against symlinking dependencies into a worktree; they recommend a fast package manager such as pnpm, bun or uv.

## What a Worktree Shares, and What Your Agent Won't Find There

A worktree shares the repository — commits, branches, stash, config — and gets its own HEAD, index and checked-out files. Nothing gitignored comes along, and nothing on your machine gets split: ports, database servers and the Docker daemon are still one of each.

Here is a fresh worktree in a repo whose `.gitignore` lists `.env` and `node_modules/`:

```console
$ git worktree add .worktrees/feature-a -b feature-a
Preparing worktree (new branch 'feature-a')
HEAD is now at b23c955 init
$ ls -A .worktrees/feature-a
.git
.gitignore
app.js
$ git -C .worktrees/feature-a rev-parse --path-format=relative --git-dir
../../.git/worktrees/feature-a
```

No `.env`. And the worktree's git directory lives inside the main checkout's `.git` (its `.git` is a one-line file pointing there); that is why sandboxed agents fail to commit, covered under errors.

| In a new worktree                    | What happens                                                      |
| ------------------------------------ | ----------------------------------------------------------------- |
| Tracked files                        | Fresh checkout of the start commit                                |
| Branches and commits                 | Shared: a commit in one worktree is visible from all of them      |
| Stash                                | Shared: a stash made in `feature-a` appears in `feature-b`'s list |
| HEAD and index                       | Per worktree                                                      |
| `.env`, `node_modules`, build output | Absent until you copy or install them                             |
| Your uncommitted edits in main       | Absent (git, Claude Code, Codex CLI); the Codex app copies them   |
| Ports, DB server, Compose project    | Same machine, same names: they collide unless you change them     |

The stash row surprises people. From my run:

```console
$ git stash list
stash@{0}: On feature-a: stash made in feature-a
$ git -C .worktrees/feature-b stash list
stash@{0}: On feature-a: stash made in feature-a
```

The [git-worktree docs](https://git-scm.com/docs/git-worktree) spell out the rule: refs under `refs/` are shared, pseudo-refs like `HEAD` are per worktree.

## Give Each Worktree Its Own .env, Port, Database and Compose Project

Copy the ignored files in, then rewrite three values so nothing on the machine collides. This script does both for any agent. It reads the same `.worktreeinclude` file Claude Code and the Codex app use, and puts worktrees in a sibling directory, outside the repo, so test runners and linters never see them:

```bash
#!/usr/bin/env bash
# wt-new <name> [base]: a sibling worktree with its own .env, port, database and Compose project
set -euo pipefail
name=$1 base=${2:-HEAD}
root=$(git rev-parse --show-toplevel)
git -C "$root" check-ignore -q .env || { echo "wt-new: add .env to .gitignore first" >&2; exit 1; }
dir="$(dirname "$root")/$(basename "$root").worktrees/$name"
git -C "$root" worktree add "$dir" -b "$name" "$base"

# Copy gitignored files that match .worktreeinclude (same file Claude Code and the Codex app read)
if [ -f "$root/.worktreeinclude" ]; then
  git -C "$root" ls-files -z --others --ignored --exclude-from=.worktreeinclude |
    while IFS= read -r -d '' f; do
      git -C "$root" check-ignore -q -- "$f" || continue
      mkdir -p "$dir/$(dirname "$f")" && cp -p "$root/$f" "$dir/$f"
    done
fi

# Lowest port no other worktree's .env has claimed
taken=$(git -C "$root" worktree list --porcelain | sed -n 's/^worktree //p' |
  while IFS= read -r wt; do sed -n 's/^PORT=//p' "$wt/.env" 2>/dev/null || true; done)
port=3001
while printf '%s\n' $taken | grep -qx "$port"; do port=$((port + 1)); done

slug=$(printf %s "$name" | tr -c 'a-zA-Z0-9' '_' | tr 'A-Z' 'a-z')
env="$dir/.env"
touch "$env"
db=$(sed -n 's/^DATABASE_URL=//p' "$env")
{
  grep -vE '^(PORT|DATABASE_URL|COMPOSE_PROJECT_NAME)=' "$env" || true
  echo "PORT=$port"
  if [ -n "$db" ]; then echo "DATABASE_URL=${db}_$slug"; fi
  echo "COMPOSE_PROJECT_NAME=$(basename "$root" | tr 'A-Z' 'a-z')_$slug"
} > "$env.tmp" && mv "$env.tmp" "$env"
echo "../$(basename "$root").worktrees/$name"
cat "$env"
```

Save it as `wt-new` on your `PATH` and `chmod +x` it. It's a bash script; I ran it on macOS. In a repo whose main `.env` holds `PORT=3000` and `DATABASE_URL=postgres://localhost:5432/myapp`:

```console
$ wt-new feature-a
Preparing worktree (new branch 'feature-a')
HEAD is now at c2879c5 compose + worktreeinclude
../myapp.worktrees/feature-a
PORT=3001
DATABASE_URL=postgres://localhost:5432/myapp_feature_a
COMPOSE_PROJECT_NAME=myapp_feature_a
$ wt-new feature-b
Preparing worktree (new branch 'feature-b')
HEAD is now at c2879c5 compose + worktreeinclude
../myapp.worktrees/feature-b
PORT=3002
DATABASE_URL=postgres://localhost:5432/myapp_feature_b
COMPOSE_PROJECT_NAME=myapp_feature_b
```

Then start any agent inside it. A hand-made git worktree needs nothing special from Claude Code — `cd ../myapp.worktrees/feature-a && claude` — and the same goes for `codex` and `agent`. Octomind is ours and has no worktree flag either: started there with `octomind run -n feature-a`, it loads that checkout's AGENTS.md and keeps a named session you can resume.

**The Compose line matters more than it looks.** Compose names a project after the directory holding the Compose file unless something overrides it ([Docker Compose project-name docs](https://docs.docker.com/compose/how-tos/project-name/)), and it reads `COMPOSE_PROJECT_NAME` from a `.env` in the working directory ([Compose environment-variable docs](https://docs.docker.com/compose/how-tos/environment-variables/envvars/)). I checked what each layout resolves to with `docker compose config` (Compose 5.1.2), against a file publishing `${PORT:-3000}:80`:

| Checkout                                   | Compose project   | Host port |
| ------------------------------------------ | ----------------- | --------- |
| Main checkout `myapp/`                     | `myapp`           | 3000      |
| `wt-new feature-a`                         | `myapp_feature_a` | 3001      |
| `wt-new feature-b`                         | `myapp_feature_b` | 3002      |
| Codex-style path `…/a1b2/myapp`, no `.env` | `myapp`           | 3000      |
| Claude-style `.claude/worktrees/feature-c` | `feature-c`       | 3000      |

The Codex row is the dangerous one: same project name as your main checkout, so `docker compose down -v` there would remove the main checkout's containers and volumes. The Claude row gets its own project but still fights for port 3000.

The script stops at naming the database. Create it and run migrations as part of setup — Cursor's own example puts `npm run db:migrate` in `worktrees.json` — and point any service that hardcodes a port at `$PORT`. It assumes `DATABASE_URL` ends in the database name with no query string, and it only avoids ports other worktrees claimed, not ports some unrelated process holds.

## node_modules: Install Per Worktree, Share the Disk

Install dependencies in every worktree; don't symlink `node_modules` between them, since a dependency change on one branch then changes it for every agent. With a warm cache the install is cheap. The disk isn't.

I installed the same seven dev dependencies (vite, vitest, typescript, eslint, typescript-eslint, react, react-dom — 100 top-level packages) into two worktrees with each package manager:

|                                       | npm 10.9.7, `npm ci` | pnpm 12.8.1, hardlink import |
| ------------------------------------- | -------------------- | ---------------------------- |
| Install time per worktree, warm cache | 0.7 s                | 0.9 s                        |
| `node_modules` in the first worktree  | 87 MB                | 92 MB                        |
| Extra disk for the second worktree    | 87 MB                | 0.24 MB                      |

npm writes a full copy per worktree. pnpm links every worktree to one content-addressable store ([pnpm docs](https://pnpm.io/motivation)), so `du` counted the second worktree's files once. At Cursor's default cap of 25 worktrees, npm's copies of this small toolchain alone would take about 2.1 GB.

On macOS, pnpm's default import method tries clone before hardlink ([pnpm settings reference](https://pnpm.io/settings/node-modules)); copy-on-write clones also share blocks, but `du` can't show it, which is why I forced hardlinks to measure. For a large monorepo, Claude Code's `worktree.sparsePaths` setting, added in 2.1.76 per the [Claude Code changelog](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md), checks out only the directories you list.

## Worktree Errors You'll Hit, and the Fix for Each

Every message below came from my scratch repo on git 2.55.0 unless marked otherwise.

- **`fatal: 'feature-a' is already used by worktree at '<path>'`** — the branch is checked out in another worktree. `git switch feature-a` in your main checkout prints the same thing. Use a new branch (`-b`), check out `--detach`, or remove the other worktree. Older git words it `is already checked out at`. In the Codex app, use Hand off instead.
- **`fatal: a branch named 'feature-a' already exists`** — you passed `-b` with an existing name. Drop `-b` to check that branch out.
- **`fatal: '.worktrees/feature-a' already exists`** — the path is taken. Pick another, or remove what's there.
- **`error: cannot delete branch 'feature-a' used by worktree at '<path>'`** — remove the worktree first, then the branch.
- **`fatal: '<path>' contains modified or untracked files, use --force to delete it`** — commit or stash, or pass `--force`. Gitignored files don't trigger this: my copied `.env` and a stub `node_modules` were deleted silently, so never keep anything only there.
- **`fatal: cannot remove a locked working tree, lock reason: …`** — `git worktree unlock <path>`, then remove. Claude Code locks the worktree while an agent runs, and headless runs leave the lock behind.
- **`prunable` in `git worktree list`, or the branch is still "in use" after you `rm -rf`'d the directory** — the metadata survived. `git worktree prune -v` printed `Removing worktrees/feature-b: gitdir file points to non-existent location`, and the branch was free again.
- **`Failed to resolve base branch "HEAD": git rev-parse failed`** (Claude Code, per its [common-workflows docs](https://code.claude.com/docs/en/common-workflows)) — the repo has no commits. Make one. Plain git 2.55 instead creates an orphan branch.
- **`fatal: Unable to create '<main>/.git/worktrees/feature-a/index.lock': Operation not permitted`** — the agent's sandbox allows writes only inside the worktree, and git writes to the main checkout's `.git`. I reproduced it with a macOS Seatbelt profile that re-allows writes only under the worktree; adding the main `.git` made the same commit succeed. Claude Code's docs say its sandbox allows these writes. Codex CLI's `--add-dir` makes an extra directory writable: pass it `$(git rev-parse --path-format=absolute --git-common-dir)`. Octomind's `--sandbox` grants writes only to the working directory plus [its state and temp paths](/docs/troubleshooting/01-common-issues), so in a linked worktree, commit from your own shell.
- **Test counts multiply, or ESLint says `No tsconfigRootDir was set, and multiple candidate TSConfigRootDirs are present`** — worktrees nested inside the repo. Exclude them (see the Claude Code section) or keep worktrees outside it.

## Merge the Agents' Work Back and Clean Up

Branches live in the shared repository, so you merge an agent's work from your main checkout without pushing anything. Preview first: two agent branches can each merge cleanly into main and still conflict with each other.

```bash
# Exit 0 = clean, 1 = conflict. Touches no files.
for b in feature-a feature-b; do
  git merge-tree --write-tree --quiet main "$b" && echo "$b: clean" || echo "$b: CONFLICT"
done
git merge-tree --write-tree --name-only feature-a feature-b   # do the agents collide?
```

In my run, both branches were clean against main, and the pairwise check caught the real problem:

```console
$ git merge-tree --write-tree --name-only feature-a feature-b
575eb286349af987878205a4d413cd43c56c876e
app.js

Auto-merging app.js
CONFLICT (content): Merge conflict in app.js
```

`git merge-tree` exits 1 on conflicts ([git-merge-tree docs](https://git-scm.com/docs/git-merge-tree)), so the loop works in a script. Merge the first branch, then rebase the second inside its own worktree, where the agent that wrote it can resolve the conflict:

```bash
git merge feature-a                                  # in the main checkout
git -C ../myapp.worktrees/feature-b rebase main      # conflicts surface here, not in main
```

Prefer pull requests? Push from inside the worktree — `git push -u origin feature-a` — exactly as from any checkout. Then tear down:

```bash
git worktree remove ../myapp.worktrees/feature-a
git branch -d feature-a          # -D if you're discarding unmerged work
git worktree prune -v            # clears metadata for directories deleted by hand
git worktree list                # should show only the main checkout
```

## Where Worktrees Stop Helping (Honest Version)

Worktrees isolate files. Everything else about parallel agents is still your problem.

**Overlapping tasks still conflict.** Two agents editing the same module produce the conflict above, just later. Split work by file or module, and run the pairwise preview before merging anything.

**The machine is still shared.** One Postgres server, one Docker daemon, the same CPU cores. Running four or five Claude agents at once, incident.io named databases, ports and local services as their open problem in 2025 ([incident.io engineering blog](https://incident.io/blog/shipping-faster-with-claude-code-and-git-worktrees)). Separate names fix collisions, not contention: several agents running full test suites at once will slow each other down.

**A worktree is a directory, not a jail.** Claude Code blocks edits, commands and git redirects that reach the main checkout from an isolated session. Other agents stay out only if their own sandbox keeps them out. If parallel agents tempt you into [running agents without permission prompts](/blog/dangerously-skip-permissions-safely), put the sandbox in place first.

**Submodules are rough.** The git docs still call multiple checkouts experimental and submodule support incomplete, and advise against multiple checkouts of a superproject.

**Worktrees aren't sub-agents.** They run separate sessions on separate branches. To split one task across helpers inside a session, use [sub-agents](/blog/multi-agent-delegation-octomind) instead.

[AUTHOR: How many parallel agents do you run before reviewing their branches becomes the bottleneck, and what breaks first?]

**[Get Octomind](https://octomind.run)** — start it in any worktree and it picks up that checkout's AGENTS.md, on any model.

## FAQ

### What is a Claude worktree?

A Claude worktree is a git worktree that Claude Code creates with `claude --worktree <name>` (or `-w`). It lives in `.claude/worktrees/<name>` on a new branch named `worktree-<name>`, so the session edits its own copy of the files while sharing the repository's history. By default it branches from the remote's default branch; set `worktree.baseRef` to `"head"` to start from your local commits.

### Does Codex support git worktrees?

Yes. The Codex CLI has `codex --worktree` and the `/worktree` command, on by default since 0.156.0 (September 2026); it creates a detached-HEAD checkout of your current commit under `~/.codex/worktrees/` and never deletes it automatically. The Codex app adds a Worktree mode, permanent worktrees, `.worktreeinclude` copying, and automatic cleanup that keeps the newest 15.

### How do I set up worktrees in Cursor?

Start an agent in a worktree from the Agents Window, with `/worktree` in the IDE, or with `agent --worktree <name>` in the CLI. Put setup commands such as `npm ci` and `cp $ROOT_WORKTREE_PATH/.env .env` under `setup-worktree` in `.cursor/worktrees.json`. Cursor stores worktrees in `~/.cursor/worktrees` and keeps the newest 25 per machine.

### Why is my .env file missing in the worktree?

Git checks out only tracked files, and `.env` is normally gitignored, so a new worktree doesn't have it. List it in `.worktreeinclude` for Claude Code or the Codex app, copy it from `$ROOT_WORKTREE_PATH` in Cursor's `worktrees.json`, or use a script like `wt-new` above. Change its `PORT` and `DATABASE_URL` per worktree so parallel agents don't share a server or database.

### How do I fix "is already used by worktree"?

The branch is checked out in another worktree, and git allows each branch in only one place at a time. Create a new branch with `-b`, check out with `--detach`, or remove the other worktree with `git worktree remove`. If you deleted that directory by hand, run `git worktree prune` first to release the branch.
