Run Claude Code agents in parallel with git worktrees
Updated 24 October 2026
Running Claude Code agents in parallel is easy until two sessions share a folder. Two Claude Code sessions in the same folder will trip over each other: one rewrites a file the other just read, a test run picks up half of someone else’s change, and git status turns into a mix of both. A git worktree gives each session its own checkout of the same repository, on its own branch. Claude Code can create them for you. Here’s how to set them up, keep them running, merge the work back and clean up.
The short answer
| Task | Command or file |
|---|---|
| Start a session in a new worktree | claude --worktree feature-auth (or -w) |
| Worktree for an existing branch, or outside the repo | git worktree add ../app-fix fix-login, then run claude there |
Copy .env into new worktrees | List it in .worktreeinclude |
| See every worktree | git worktree list |
| Remove one | Exit the session and choose remove, or git worktree remove <path> |
| Know which session needs you | Name sessions, alerts with the worktree name, or Agent Pets |
1. Why a worktree and not a second clone
A worktree is an extra working directory attached to your existing repository. It has its own files and its own checked-out branch, but shares the .git directory with your main checkout: the same history, remotes, stashes and config. A commit made in one worktree shows up in git log everywhere straight away, with no push or fetch in between.
That’s what makes it a good fit for agents. Each session edits its own files and runs its own tests, and you merge the branches when they’re done, the same way you’d merge a colleague’s work. A second git clone also isolates files, but it downloads everything again and you have to push and pull to move commits between copies.
One rule to know before you start: git lets a branch be checked out in only one worktree at a time. Try to check out main in a second worktree and you get:
Terminalfatal: 'main' is already checked out at '/Users/you/code/app'
So each parallel session works on its own branch. That’s what you want anyway.
2. Let Claude Code create the worktree
Claude Code has this built in. Start a session with --worktree (short form -w) and a name:
Terminalclaude --worktree feature-auth
Claude Code creates the worktree at .claude/worktrees/feature-auth/ in your repository root, on a new branch called worktree-feature-auth, and starts the session there. Open another terminal and run it again with a different name for a second, fully separate session. Leave the name out and Claude picks one for you, such as bright-running-fox.
Things to know:
- Add the folder to
.gitignore. Otherwise.claude/worktrees/shows up as untracked files in your main checkout. - It branches from the remote default branch, usually
origin/main, not from what you have checked out. To start from your currentHEADwith its unpushed commits, set"worktree": { "baseRef": "head" }in your settings. It doesn’t accept a branch name; for a specific existing branch, usegit worktree add(section 3). - Pull requests work too.
claude --worktree "#1234"fetches that pull request fromorigininto.claude/worktrees/pr-1234. Keep the quotes, or your shell treats#as a comment. - Trust comes first. If you’ve never run Claude in the repository,
--worktreeexits with an error until you run plainclaudethere once and accept the trust dialog. - Reusing a name reopens it. If
.claude/worktrees/feature-authalready exists, the same command opens that worktree instead of making a new one. - tmux. Add
--tmuxto open the worktree session in its own tmux session (iTerm2 native panes when available,--tmux=classicfor plain tmux).
While a session is in its worktree, Claude Code blocks edits and commands aimed at your main checkout, including git -C tricks, so a session can’t wander back and touch your working copy. It doesn’t track every file a shell command writes, though: a cp into the main checkout is treated like any other command under your permission rules.
You can also ask Claude mid-session to “work in a worktree” and it moves itself into one. Background sessions started from claude agents or claude --bg do this on their own: before the first edit, Claude moves the session into a worktree under .claude/worktrees/.
3. Or create worktrees yourself with git
Use plain git when you want a specific existing branch, or a folder outside the repository, such as next to it:
Terminal# new branch, new folder next to the repo
git worktree add ../app-feature-a -b feature-a
# existing branch
git worktree add ../app-bugfix fix-issue-456
# start Claude in it
cd ../app-feature-a
claude
A naming habit that pays off: name the folder after the repository plus the task (app-feature-a), and the branch after the task. When five terminals are open, the folder name in the prompt and window title is how you tell them apart. With --worktree, the branch is always worktree-<name>, so pick names you’d be happy to see in a pull request, or rename the branch before you push.
To see everything you have:
Terminalgit worktree list
It prints each worktree’s path, commit and branch. Claude Code’s worktrees appear here too.
4. Install dependencies and copy .env in each worktree
A new worktree contains only tracked files. No node_modules, no virtualenv, no build output and no .env. The first test run fails until you set it up, so either ask Claude to install dependencies as its first step or do it yourself:
Terminalcd .claude/worktrees/feature-auth
npm install # or pnpm install, uv sync, bundle install…
For gitignored files such as .env, add a .worktreeinclude file to the project root. It uses .gitignore syntax, and Claude Code copies every file that both matches and is gitignored into each worktree it creates, including subagent worktrees:
.worktreeinclude.env
.env.local
config/secrets.json
It only runs for worktrees Claude Code creates. For worktrees you made with git worktree add, copy the files yourself: cp .env ../app-feature-a/.
If installing per worktree is too slow or eats too much disk, Claude Code can symlink directories from the main checkout instead:
.claude/settings.json{
"worktree": {
"symlinkDirectories": ["node_modules"]
}
}
The catch: every worktree then shares one node_modules. If a session adds or upgrades a package, the others see it too, and two branches with different dependencies will break each other. Symlink only when the branches share the same lockfile. In a large monorepo, "sparsePaths": ["packages/my-app"] under worktree checks out only the folders you list, plus root-level files.
Some things carry across without setup: plugins installed at project scope, and “Yes, and don’t ask again” approvals, which Claude Code saves to the main checkout’s .claude/settings.local.json so every worktree gets them. On Windows, that approval stays with the worktree it was given in.
5. Avoid port and database clashes
Worktrees isolate files, not your machine. Two sessions that each start a dev server on port 3000 collide: some dev servers move to the next free port and tell you, others fail with EADDRINUSE. And if .worktreeinclude copies the same .env everywhere, every worktree gets the same PORT and DATABASE_URL.
- Give each worktree its own port. Put
PORT=3001in that worktree’s.env.local(if your framework reads it), or tell the session in its first prompt which port to use. - Separate databases. Two sessions running migrations against one local database will fight. Point each worktree at its own database name, or keep sessions that touch the schema to one at a time.
- Docker Compose names its project after the folder by default, so containers in different worktrees don’t share names. Published host ports still clash; set them through variables in your compose file.
- Watch for leftovers. A dev server a session started in the background keeps running after you close the session.
lsof -i :3000on macOS and Linux shows what holds a port.
6. Merge the work back
Each worktree is just a branch, so you merge it like any other. Commit in the worktree first (or ask Claude to), then pick one:
Terminal# open a pull request from inside the worktree
git push -u origin worktree-feature-auth
gh pr create
# or merge locally, from your main checkout
cd ~/code/app
git merge worktree-feature-auth
Because all worktrees share one repository, the main checkout sees the branch the moment it’s committed. If main moved on while the session worked, update the branch from inside the worktree with git fetch origin and git rebase origin/main before merging. Parallel sessions are most useful when their tasks touch different parts of the code. Two sessions refactoring the same module will still give you a merge conflict at the end; worktrees only move it from “while they work” to “when you merge”.
7. Clean up
When you exit a --worktree session, Claude Code checks for changed or untracked files and new commits:
- Nothing changed: an unnamed session’s worktree and branch are removed automatically. A named session asks first.
- Work in it: Claude Code asks whether to keep or remove it. Keep it and it prints a
claude --worktree <name> --resumecommand to come back later. Remove deletes the folder, the branch and everything in them.
Worktrees from -p runs and ones you created yourself need removing by hand:
Terminalgit worktree remove ../app-feature-a
git branch -d feature-a
The errors you’ll meet:
contains modified or untracked files, use --force to delete it: commit or copy out anything you want, then add--force.- Git refuses because the worktree is locked: Claude Code locks worktrees while a session runs. Stop the session, or run
git worktree unlock <path>first. Cannot delete branch … checked out at …: remove the worktree before the branch. Use-Dinstead of-dfor a branch you never merged.- You deleted the folder with
rm -rf:git worktree listmarks itprunable;git worktree pruneclears the record.
Background sessions and subagents clean up after themselves: claude rm <id> deletes a background session and its worktree when that’s safe, and a periodic sweep removes old, clean subagent and background worktrees after your cleanupPeriodDays. It never touches worktrees with uncommitted work or unpushed commits, or ones you made with git worktree add.
8. How many parallel agents to run at once
Git doesn’t care how many worktrees you have. The limits are your machine, your plan’s usage limits, and mostly you. Every session ends with a diff someone has to read, and while you review one, the others stop at permission prompts and wait.
A workable pattern is two or three sessions on unrelated tasks you could describe in a sentence each, plus one you’re actively steering. Push past that only when the extra work is low-risk and quick to review, such as dependency bumps or test fixes. If you catch yourself approving prompts without reading them, you have too many going.
9. Keep track of which session needs you
With several worktrees, the hard part isn’t running sessions, it’s noticing that one has been waiting on a permission prompt for ten minutes.
- Name them.
claude -w feature-auth -n authsets a display name shown in the prompt box, the/resumepicker and the terminal title. In a running session, use/renameand/color. - Agent view. Run
claude agentsto dispatch background sessions, each in its own worktree, and see them grouped under Needs input, Working and Completed. It lists background sessions only. - Put the worktree in the alert. Every hook gets the session’s
cwd, which is the worktree root, so a notification hook that showsbasenameof it tells you which session is asking. The script is in How to keep track of multiple Claude Code sessions. Readcwdrather than${CLAUDE_PROJECT_DIR}: when Claude moves into a worktree mid-session,${CLAUDE_PROJECT_DIR}keeps pointing at the folder the session started in.
See every worktree session from your browser with Agent Pets
If you spend the wait in Chrome, reviewing one session’s pull request while the others work, Agent Pets puts every session on the page you’re on:
- Each Claude Code, Codex, OpenCode and omp session gets its own named pet that walks along the bottom of every page, one per worktree.
- A capsule over each pet says Thinking, Allow Bash?, Your Turn or Done, and the toolbar badge counts the sessions waiting on you.
- When a session wants to run a command or edit a file, its pet bounces. Click it and answer Allow, Always or Deny right there, without finding the right terminal.
- Read any session’s latest answer and send its next message from the tab you’re on.
- In another app, a desktop notification names the pet that needs you, with Allow and Deny on it.
npx getagentpets init adds the Claude Code hooks for you, next to any you already have. It runs entirely on your computer, and each terminal keeps its own prompt, so you can answer in either place.
Get Agent Pets — was $25, now $6Get Agent Pets — $25
Questions
Does Claude Code support git worktrees?
Yes. Run claude --worktree <name> (or -w) and Claude Code creates a worktree under .claude/worktrees/<name>/ on a new branch called worktree-<name>, then starts the session in it. You can also ask Claude to work in a worktree mid-session, or start Claude inside a worktree you made with git worktree add.
How do I get my .env file into a Claude Code worktree?
Add a .worktreeinclude file to the project root with one pattern per line, such as .env and .env.local. Claude Code copies files that match and are gitignored into every worktree it creates. Worktrees you make with git worktree add don’t get them, so copy those by hand.
Why does git say a branch is already checked out?
Git lets each branch be checked out in only one worktree at a time. Create the worktree on a new branch with -b, or switch the other worktree to a different branch first.
How do I delete a Claude Code worktree?
Exit the session and choose to remove it when Claude Code asks; a clean worktree from an unnamed session is removed automatically. Otherwise run git worktree remove with its path, add --force if it has uncommitted changes, run git worktree unlock first if git says it is locked, and delete the branch with git branch -D.
Can I run multiple Claude Code sessions in parallel on the same repository?
Yes, as long as each one works in its own worktree. Start each with claude --worktree <name>, or point each at a folder made with git worktree add. Sessions sharing one folder overwrite each other’s files and mix their changes in git status.
Sources: Claude Code’s documentation on worktrees, settings, agent view and hooks; claude --help (v2.1.287); the git worktree documentation.