Claude Code Git Worktrees: How to Run Isolated Parallel Work
Last updated: April 15, 2026
Claude Code Git Worktrees
Quick answer
A git worktree is a separate working directory linked to the same .git repository but checked out on a different branch. For Claude Code, worktrees let multiple sessions or subagents work on the same repo in parallel without conflict. Create one with git worktree add ../feature-branch feature-branch, list with git worktree list, remove with git worktree remove. Watch for shared node_modules, lock file conflicts, and DATABASE_URL clashes.
What a git worktree is
A worktree is a second working directory tied to the same git repository. The .git directory stays in the main repo; each worktree gets a lightweight pointer. Each worktree has its own working files, its own checked-out branch, and its own HEAD.
You can have many worktrees for one repo. Each one can be on a different branch. Commits from one worktree are immediately visible to the others because they share the object database.
Create one:
git worktree add ../myrepo-feat-login feat/login
This creates ../myrepo-feat-login/ with feat/login checked out. cd ../myrepo-feat-login and you are on that branch, with a full working tree, independent of the original directory.
Why worktrees matter for Claude Code
Three reasons:
- Parallel sessions. Run two Claude Code sessions in two terminal windows, each in its own worktree, working on separate features at the same time. No branch-switch friction, no stash juggling.
- Subagent isolation. Dispatch a subagent into its own worktree so its edits do not touch the parent's working files. Clean separation.
- Experimentation. Spin up a throwaway worktree to let Claude try a risky refactor. If it goes wrong, delete the worktree; the main branch is untouched.
Without worktrees, the alternatives are branch-switching (which loses uncommitted changes or forces stashes) or cloning the repo (which is heavier and duplicates the .git directory).
Creating and cleaning up
Starter commands:
# Create a worktree on a new branch
git worktree add -b feat/login ../myrepo-feat-login
# Create on an existing branch
git worktree add ../myrepo-bugfix bugfix/issue-42
# List all worktrees
git worktree list
# Remove a worktree (after merging or abandoning the branch)
git worktree remove ../myrepo-feat-login
# Clean up metadata for deleted worktrees
git worktree prune
The main worktree (the original checkout) cannot be removed; removing any other worktree deletes the directory but leaves the branch and its commits intact.
The EnterWorktree / ExitWorktree pattern
Claude Code's agent runtime has two helper tools for worktree-based subagents:
EnterWorktree: creates or switches to a worktree and continues work inside it.ExitWorktree: returns to the parent's working directory, optionally committing or merging changes.
A typical subagent flow:
- Parent calls
EnterWorktreewith a branch name. - Subagent runs in the new worktree, reads files, edits, runs tests.
- Subagent commits on the branch.
- Parent calls
ExitWorktree. The branch exists in the main repo, ready for review or merge.
This pattern is the cleanest way to run parallel subagents without stepping on each other.
Parallel work setup
Here is a script that creates N worktrees for N independent tasks:
#!/usr/bin/env bash
set -euo pipefail
TASKS=("auth" "billing" "search")
REPO_ROOT="$PWD"
for task in "${TASKS[@]}"; do
git worktree add -b "feat/$task" "../$(basename $REPO_ROOT)-$task"
done
echo "Worktrees ready:"
git worktree list
Run Claude Code once per worktree:
cd ../myrepo-auth && claude --print "Implement auth refactor per docs/auth-plan.md" &
cd ../myrepo-billing && claude --print "Implement billing refactor per docs/billing-plan.md" &
cd ../myrepo-search && claude --print "Implement search refactor per docs/search-plan.md" &
wait
Three sessions run in parallel. Each commits on its own branch. Once all finish, review and merge one at a time.
Gotchas
Shared node_modules
Each worktree needs its own node_modules if the package manager does not support symlinked caches. With pnpm, the global store is shared, so pnpm install in each worktree is fast. With npm or yarn classic, each install is fresh and slow.
Fix: use pnpm, or symlink node_modules from the main worktree if the worktrees are all on compatible lockfiles. Do not share node_modules across worktrees on different versions of a dependency.
Lock file conflicts
If two worktrees run pnpm install at the same time and end up updating the lockfile differently, the merge is messy. Avoid concurrent installs. Run installs serially or only in the worktree that needs a new dependency.
Database URL clashes
Two worktrees using the same local Postgres DB will step on each other. Use separate test databases per worktree, or a docker-compose setup that runs one DB per worktree. An env var pattern that works well:
export DATABASE_URL="postgresql://localhost/myapp_$(basename $PWD)"
Each worktree gets a unique database name derived from its directory.
Environment files
.env.local is not version-controlled, so it does not copy to a new worktree. Either copy it in manually after creation or symlink from the main worktree:
ln -s "$MAIN_REPO/.env.local" .env.local
Dev server ports
Two worktrees running pnpm dev at the same time fight over port 3000. Override in each:
PORT=3001 pnpm dev # in the second worktree
Cleaning up after sessions
Stale worktrees clutter the filesystem and confuse future branches. Two cleanup strategies:
- Manual. After merging a branch, run
git worktree remove ../myrepo-feat-loginand thengit branch -d feat/loginif the branch is also done. - Automated. Add a Stop hook to Claude Code that removes the worktree on session end if the branch has been merged. Example:
#!/usr/bin/env bash
branch=$(git rev-parse --abbrev-ref HEAD)
if git merge-base --is-ancestor HEAD main; then
cd ..
git worktree remove "$(basename $OLDPWD)"
git branch -d "$branch"
fi
Hook this into Stop in your project settings.json when you want aggressive cleanup.
Worktree vs clone
Both give you a separate working directory. The differences:
- Worktree shares the
.gitobject database. Disk usage is tiny, fetches are instant, commits are immediately visible across worktrees. - Clone has its own
.git. Fully independent, but fetches are slower and disk usage is higher.
For parallel work on the same remote, worktrees are almost always the right choice.
When NOT to use worktrees
Three situations where a worktree adds overhead without benefit:
- Small single-file tasks. Editing a README or a single line in one file does not justify a worktree.
- Tasks that touch only
main. No branch, no worktree needed. - Quick experiments you plan to
git reset --hardaway. A stash is simpler.
Worktrees shine when the task is large, the branch matters, and you want to keep the parent's working tree clean.
Common commands reference
# Create and check out a new branch in a new worktree
git worktree add -b feat/x ../repo-feat-x
# Create on an existing local branch
git worktree add ../repo-bugfix bugfix/issue-42
# Create from a remote branch
git worktree add ../repo-upstream origin/upstream
# List all worktrees with branch info
git worktree list
# Remove (directory must have no uncommitted changes)
git worktree remove ../repo-feat-x
# Force-remove even with uncommitted changes
git worktree remove --force ../repo-feat-x
# Prune metadata for manually-deleted directories
git worktree prune
Git ships these commands in every version since 2.5, so no extra install is required.
Why parallel agents change workflow
Worktrees are cheap in disk and setup, but the real shift comes when you combine them with subagent dispatch and realize that a feature which used to take a single long focused session can now be split into three medium-length sessions running simultaneously in three separate branches, each with its own Claude Code instance making independent decisions, each producing a branch ready for review, and the only human work left is reading three short PR descriptions and clicking merge in an order that avoids conflicts; this is a different shape of work than sequential agent use, and teams who pick it up usually report 2-3x throughput on features that fit the pattern. Short tasks stay sequential.
Worktrees in CI
CI environments rarely benefit from worktrees since every job starts fresh. The exception: matrix jobs that run different branches against each other. In that case, one checkout plus one worktree per matrix entry is cheaper than multiple clones. Most CI setups instead use separate checkouts per job, which is simpler.
Frequently asked questions
Can two worktrees run the same app at once?
Yes, as long as you avoid port and resource conflicts. Override the dev server port with `PORT=3001 pnpm dev` in the second worktree and give each worktree its own test database via a unique DATABASE_URL.
How do I merge worktree changes back to main?
Commit on the branch inside the worktree, switch to your main repo's working tree, and run `git merge feat/x` or open a PR. The commits are already in the shared `.git` database, so no extra sync step is needed.
Do worktrees share node_modules?
No. Each worktree needs its own install unless you symlink. With pnpm the global store is shared so per-worktree installs are fast. With npm or yarn classic, each install is a full download.
What is the difference between a worktree and a clone?
A worktree shares the `.git` object database with the main repo, so disk usage is tiny and commits are visible across worktrees immediately. A clone has its own `.git` directory and is fully independent but slower to sync.
How do I clean up stale worktrees?
Run `git worktree remove <path>` for a specific worktree, or `git worktree prune` to clear metadata for directories that were manually deleted. A Stop hook can automate cleanup at session end for branches that have been merged.
Do worktrees help in CI?
Rarely. CI jobs start fresh, so there is no working state to preserve. The exception is matrix jobs running different branches in the same container, where one checkout plus per-branch worktrees beats multiple clones on disk and time.