← Alle Playbooks
Playbook· build

Running parallel Claude Code sessions with git worktrees

How to work on several branches at once with Claude Code without ending up in stash hell. One worktree per branch, one session per worktree, no switching.

Stash, branch, pull, "wait, what is actually going on here", anyone using Claude Code as a daily driver knows the effect. A bug fix comes in while the feature branch is half finished. Three stashes pile up. A reviewer sends a change on the old PR, you have to switch briefly, but forget that an edit is still open in the current repo. Git worktrees solve that by putting every branch in its own directory. One Claude Code session per directory. No switching, no stashing, no "where was I again".

This playbook shows the setup I have been running for over a month. Four to six worktrees in parallel is realistic. One per active task.

Step 1: Understand what a worktree does

A normal git repo has exactly one working tree. When you switch branches, the content in the same directory changes. A worktree, by contrast, is an additional directory connected to the same .git data store but with its own branch checked out. Four worktrees mean four directories, four branches visible at once, one shared commit graph.

That saves disk space, because internally git only holds the objects once. And it makes working with Claude Code predictable, because every session has a clearly bounded directory. No "why has the code changed in my other terminal tab" moments.

Step 2: Decide on a directory layout

Before you create the first worktree, settle on a layout. I use:

~/projects/
  my-project/                  # main repo, main branch
  my-project-feat-auth/        # worktree for a feature
  my-project-fix-stripe/       # worktree for a bugfix
  my-project-pr-12/            # worktree for a PR review

Important: no worktrees inside the main repo. That works technically, but Claude Code goes mad while indexing. Side by side is clean.

Step 3: Create the first worktree

In the main repo:

cd ~/projects/my-project
git worktree add ../my-project-feat-auth -b feat/auth

That creates the new directory and at the same time creates a new branch feat/auth. If you want to work on an existing branch because a reviewer sent you something:

git worktree add ../my-project-pr-12 origin/feat/payment-refactor

git worktree list shows you at any time what you have. If you get lost at the start, that helps.

Step 4: Start Claude Code in the worktree

In every worktree directory you start its own Claude Code session. My setup: one iTerm tab per worktree, with the branch name in the tab title. With VS Code the same via workspaces.

cd ~/projects/my-project-feat-auth
claude

Worth knowing: Claude Code reads the CLAUDE.md from the current working directory. If your main repo has a CLAUDE.md, the worktree has it too, because it can be the same branch or the file was merged along. Changes to the file are branch-specific though. That is a feature, not a bug. If you want a worktree-specific instruction, put a CLAUDE.local.md in the worktree directory. You git-ignore it in .gitignore, and Claude Code pulls it in automatically.

Step 5: Vary models per worktree

This is where the pattern gets genuinely useful. Every worktree can run a different model. An example setup I have at the moment:

  • my-project/ (main, main repo), Opus 4.7, for architecture questions and larger refactors
  • my-project-feat-auth/, Sonnet 4.6, a clearly bounded feature of medium complexity
  • my-project-fix-stripe/, Haiku 4.5, a 30-line bugfix
  • my-project-pr-12/, Sonnet 4.6, because I want to understand the review diff

That saves cost and latency at the same time, because Haiku answers come back in under two seconds while Opus thinks long on the difficult question. Model choice per session at startup or via /model in the running chat.

Step 6: Plan the merge back

Worktrees are no substitute for clean branching. When a feature is finished, you merge or rebase the branch back into main as always. My flow:

cd ~/projects/my-project
git fetch origin
git merge --ff-only origin/main          # keep main current
git merge --no-ff feat/auth              # or rebase, depending on repo policy

As long as the worktree exists, the branch is checked out there and you cannot check it out in the main repo in parallel. That is intentional. Git prevents duplicate work here.

Step 7: Delete the worktree again

When the branch is merged and the worktree is empty:

git worktree remove ../my-project-feat-auth

If the directory is already gone (deleted with rm -rf for instance), the worktree entry hangs around in the main repo. git worktree prune cleans that up. Once a week is enough.

Step 8: Combine with subagent worktree isolation

If you run subagents, you can set isolation: "worktree" in a subagent's frontmatter. That is a different level from the user pattern described here. The subagent then spawns itself into a fresh, ephemeral worktree, does its job, and when it is done merges the diff back or discards it. You normally do not see these worktrees, because they are managed internally by Claude Code.

Rule of thumb: user worktrees for tasks that last longer than one session (features, reviews). Subagent worktrees for short-lived, isolated jobs (code review, refactor test). You may use both in parallel. Details on the subagent pattern are in the playbook "Your first subagent in 30 minutes".

Step 9: Traps that cost me time

Three things happened to me in the first two weeks:

First: Node node_modules is separate per worktree. If you run npm install in the main repo, the worktree has nothing. That is consistent with git behaviour, but if you switch and forget to install, you get strange errors. Solution: pnpm with node-linker=hoisted across all worktrees, or simply remember.

Second: .env files are in .gitignore in most repos. Meaning: your new worktree has no .env. Solution: a cp ~/projects/my-project/.env ../my-project-feat-auth/.env right after git worktree add. I built that as a shell function wta (worktree-add) that does both.

Third: if your repo has submodules, the new worktree does not get them automatically. git submodule update --init --recursive in the new directory solves that.

Step 10: Bring it together cleanly with memory hooks

If you use memory hooks or your own skill that writes a session ID per project, make sure the hook recognises the working directory correctly. Branch name plus worktree path is normally enough as a session key. In my setup every worktree session lands in the same memory store, but with a tag naming the branch. That way the memory recall the next day still shows where which thought came from.

If your hook cannot do that, it is a hint that the hook logic is outdated and only knows the repo root. The playbook "Repairing memory drift" says how to update it.

What next

Once the worktree setup is running, the next sensible step is either subagents (playbook "Your first subagent in 30 minutes") or, if you are still unsure about the git pattern, the mini module "Git for AI" in level 1, specifically lesson 9 on branches and reviews. If you want to bring the pattern to a team, the playbook "Claude Code in a team, maintaining CLAUDE.md together" is the next stage.

Sources

  • Git worktree docs: https://git-scm.com/docs/git-worktree
  • Subagent worktree isolation: see recipe 3.3 Subagent basics (frontmatter field isolation)
Running parallel Claude Code sessions with git worktrees — StudioMeyer Academy