Git Worktree Parallelism skill for Claude Code

Several Claude sessions, one repo, zero collisions. Lets you run two to four Claude Code sessions at once without them trampling each other. Claude splits work into tasks with disjoint file scopes, creates a worktree and branch per task, makes each checkout runnable with its own env file, port and database, hands every session a written contract, then rebases and merges in a planned order and removes everything afterwards only with your confirmation.

  • namegit-worktree-parallelism
  • size186 lines · ≈1,950 tokens
  • files1
  • licenseMIT
  • updated

What Claude sees before loading it

This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.

description: Runs several Claude Code sessions in parallel on one repository using git worktrees, with one branch, environment, port, and database per worktree, a written task contract per session, a merge order that avoids conflicts, and safe cleanup. Use when the user wants Claude working on multiple features or bugs at once, to try two approaches side by side, keep a long task running while fixing something else, or clean up stale worktrees and branches.

Try asking

  • Set up worktrees so Claude can build search and fix the cart bug at the same time
  • Try both caching approaches in parallel worktrees and compare them
  • Clean up all the old worktrees and merged branches in this repo

Use it when

  • Two or more independent tasks could progress at the same time
  • You want to compare competing implementations side by side
  • A long session is running and an urgent fix comes in
  • Stale worktrees and branches have piled up

Skip it when

  • The tasks touch the same files or depend on each other — run them sequentially
  • You only need isolated read-only research — use subagent-design instead
  • Rewriting or repairing commit history — use git-history-surgery instead

How to check the result

Each worktree passes its tests alone, each branch's changed files stay inside its contract scope, and main stays green after every merge.

The common mistake it prevents

Letting parallel worktrees share one dev server port or one database, so tests silently run against the other branch's code or schema.

~/.claude/skills/git-worktree-parallelism/SKILL.md

--- name: git-worktree-parallelism description: Runs several Claude Code sessions in parallel on one repository using git worktrees, with one branch, environment, port, and database per… license: MIT ---

Parallel sessions pay off only when the tasks are independent at the file level. Done well means: each worktree is a fully working checkout (dependencies, env files, its own port and database), each session has a written scope it stays inside, branches merge back through normal review in a planned order, and nothing is left behind afterwards.

Should this run in parallel?

Good fitPoor fit
Independent features in different modulesChanges that touch the same files or the same shared types
A bugfix while a long feature session continuesA refactor everyone else depends on (do it first, alone)
Two competing approaches to compare, one to be discardedSequential steps where B needs A’s result
Long-running work (migration rehearsal, big test runs) beside normal workMultiple schema migrations against one database

Practical ceiling: 2-4 active sessions. Review capacity, not machine capacity, is the bottleneck.

Workflow

- [ ] 1. Split work into tasks with disjoint file scopes; write a contract per task
- [ ] 2. Create one worktree + branch per task from fresh origin/main
- [ ] 3. Make each worktree runnable (deps, env, port, DB)
- [ ] 4. Start one Claude session per worktree with its contract
- [ ] 5. Monitor; keep each session inside its scope
- [ ] 6. Rebase, test, and merge in the planned order
- [ ] 7. Remove worktrees and branches (confirm before forcing anything)

1. Task contract

Give each session a self-contained brief as its first prompt (or a TASK.md that is gitignored):

Task: Add full-text search to the products API
Branch: feat/product-search   Worktree: ../shop-wt/search
In scope: packages/api/src/search/**, packages/api/test/search/**, docs/search.md
Out of scope: packages/db/schema (owned by feat/inventory), any shared UI components
Done when: `pnpm --filter api test` passes, new endpoint documented, no files outside scope changed
Commands: dev `PORT=3101 pnpm --filter api dev`; tests `pnpm --filter api test`
If you need an out-of-scope change: stop and describe it instead of making it.

2. Create worktrees

Prefer a sibling directory so test runners, linters, and file watchers in the main checkout do not crawl the other worktrees.

git fetch origin
git worktree add -b feat/product-search ../shop-wt/search origin/main
git worktree add -b fix/cart-rounding  ../shop-wt/cart   origin/main
git worktree list

If worktrees must live inside the repo (.worktrees/), add that directory to .gitignore and to the ignore settings of the test runner, linter, TypeScript exclude, and bundler.

3. Make each worktree runnable

Untracked files do not come with a new worktree. Check each item:

ItemAction
.env, .env.local, local configCopy from the main checkout (never commit)
.claude/settings.local.json, CLAUDE.local.mdCopy if the session should share your local permissions/notes
DependenciesInstall per worktree (pnpm install --frozen-lockfile; pnpm/uv caches keep it cheap)
Dev server portUnique per worktree (PORT=3101, 3102, …)
DatabaseSeparate DB name or schema per worktree; never run two branches’ migrations against one DB
Docker ComposeUnique COMPOSE_PROJECT_NAME per worktree so containers and volumes do not collide
Submodulesgit submodule update --init --recursive in each worktree
Generated codeRun codegen in each worktree (pnpm codegen, prisma generate)
cd ../shop-wt/search
cp ../../shop/.env.local .
pnpm install --frozen-lockfile
createdb shop_search 2>/dev/null; echo "DATABASE_URL=postgres://localhost/shop_search" >> .env.local
pnpm db:migrate && pnpm --filter api test     # prove the worktree works before Claude starts

4. Start sessions

  • Launch claude from inside each worktree directory, one terminal (or tmux window) per worktree. Each session loads that checkout’s CLAUDE.md and .claude/ config.
  • Session history is keyed to the directory, so claude --continue and /resume inside a worktree find that worktree’s sessions.
  • Recent Claude Code versions can create and manage worktrees themselves; check claude --help for a worktree option before scripting your own.
  • Add a Notification hook (see hooks-automation) so you know which session is waiting.

5. Monitor

Status of all worktrees at a glance:

git worktree list --porcelain | awk '/^worktree /{print $2}' | while read -r wt; do
  printf '%-36s %-26s %s changed\n' "$wt" "$(git -C "$wt" branch --show-current)" \
    "$(git -C "$wt" status --porcelain | wc -l | tr -d ' ')"
done

Scope check for a branch against its contract:

git -C ../shop-wt/search diff --name-only origin/main...HEAD

Any path outside the contract’s scope is a conversation with that session, not something to merge silently.

6. Merge order

  1. Merge foundational or smallest changes first (shared types, schema, config).

  2. For each remaining branch, in its own worktree:

    git fetch origin && git rebase origin/main
    pnpm install --frozen-lockfile && pnpm test
    git push --force-with-lease -u origin HEAD    # own feature branch only
  3. Open a PR per branch; review as usual. Never merge worktree branches into each other locally to “save time”.

  4. Conflict rules: resolve in the later branch’s worktree; regenerate lockfiles rather than hand-merging them; renumber migrations so they apply in merge order.

  5. Comparing two approaches: pick the winner from the diffs and test results, then delete the loser’s worktree and branch.

7. Cleanup

git worktree remove ../shop-wt/search      # refuses if there are uncommitted changes - good
git branch -d feat/product-search          # -d refuses unmerged branches - good
git worktree prune                         # clears metadata for directories deleted by hand
dropdb shop_search                         # per-worktree database, after confirming

git worktree remove --force, git branch -D, and dropping databases destroy work. Show the user what would be lost (git -C <wt> status, git log origin/main..<branch>) and get explicit confirmation first.

Gotchas

  • A branch can be checked out in only one worktree. Create a new branch per worktree.
  • The stash, git config, and .git/hooks are shared by all worktrees. A stash made in one is visible (and poppable) in another.
  • Deleting a worktree folder with rm -rf leaves stale metadata; run git worktree prune.
  • Two sessions running dev servers on the default port: the second silently fails or hits the first one’s server, so tests pass against the wrong code.
  • Shared database: one branch’s migration breaks the other branch’s tests in confusing ways. Isolate databases.
  • Nested worktrees inside the repo get picked up by jest, tsc, eslint ., and file watchers, doubling test runs and type errors.
  • Long-lived worktrees drift from main. Rebase daily or keep tasks short.

Verification

  • git worktree list matches the plan; each worktree’s tests pass on its own before any merge.
  • Each branch’s diff --name-only stays inside its contract scope.
  • After each merge, main builds and passes the full suite before the next branch is rebased.
  • After cleanup, git worktree list shows only the main checkout and no merged branches remain locally.

Output

| Worktree | Branch | Scope | Port/DB | Status |
|---|---|---|---|---|
| ../shop-wt/search | feat/product-search | api/src/search/** | 3101 / shop_search | PR #412, green |
| ../shop-wt/cart | fix/cart-rounding | api/src/cart/** | 3102 / shop_cart | merged, removed |
**Merge order:** cart -> search (rebased after cart, tests green)
**Cleanup:** 1 worktree remaining (search, awaiting review); prune run; 0 orphan branches

About this skill

Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.

esc