Back to blog
workflowgitclaude guide

Git Worktree Workflow for Parallel Claude Code Sessions

·10 min read

A comprehensive guide to using Git worktrees to run multiple Claude Code sessions simultaneously (without file conflicts, context collisions, or branch juggling).

Table of Contents#

  1. What Are Git Worktrees?
  2. Why Use Worktrees with Claude Code?
  3. Prerequisites
  4. Creating and Starting Worktree Sessions
  5. Working Inside a Worktree
  6. Managing Multiple Parallel Sessions
  7. Merging Work Back to Main
  8. Cleanup and Maintenance
  9. Common Gotchas and How to Avoid Them
  10. Real-World Example Workflow
  11. Quick Reference

What Are Git Worktrees?#

Git worktrees let you check out multiple branches of the same repository into separate working directories at the same time. Each worktree has its own files, its own staging area, and its own HEAD, but they all share the same .git object store and history.

Think of it this way: normally, switching between branches means stashing or committing everything, running git checkout, and waiting for the file system to update. With worktrees, every branch lives in its own folder. You can have main open in one terminal, feature-auth in another, and fix-payment-bug in a third — all simultaneously, all independent.

How worktrees differ from clones#

AspectWorktreeSeparate Clone
Disk usageLightweight: shares .git objectsFull copy of entire repo
History sharingImmediate and same object storeRequires fetch/push to sync
Branch lockingCannot check out the same branch in two worktreesNo restrictions
Setup speedInstant (seconds)Depends on repo size
Cleanupgit worktree removeDelete entire directory

Worktrees are the better choice for parallel work within a single project because they're fast, lightweight, and keep everything connected.

Why Use Worktrees with Claude Code?#

Claude Code works best when it has full ownership of the working directory. When Claude is editing files, running tests, installing dependencies, or iterating on a solution, it expects to be the only actor making changes to that file tree.

Running two Claude Code sessions in the same directory causes problems:

  • File conflicts: Both sessions edit the same file and overwrite each other's changes.
  • Branch confusion: One session commits to a branch the other session didn't expect.
  • Test interference: One session's test run picks up uncommitted changes from the other.
  • Dependency churn: One session runs npm install and changes node_modules while the other is mid-build.

Worktrees solve all of this. Each Claude Code session gets its own isolated directory, its own branch, and its own file state. They can run in parallel without stepping on each other.

Prerequisites#

Before using worktrees, make sure you have:

  • Git 2.5+ (worktrees were introduced in Git 2.5; modern features require 2.17+)
    git --version
    
  • Claude Code installed and configured
    claude --version
    
  • A Git repository that is not a shallow clone (worktrees require full history access)
    # If you have a shallow clone, unshallow it first
    git fetch --unshallow
    

Creating and Starting Worktree Sessions#

The easy way: claude --worktree

Claude Code has built-in worktree support. Just pass a name:

claude --worktree feature-auth

This single command does three things:

  1. Creates a directory at .claude/worktrees/feature-auth/ containing a full working copy of the repo.
  2. Creates a branch named worktree-feature-auth based on your current branch (usually main).
  3. Starts a Claude Code session inside that directory, ready to work.

You can spin up as many as you need with each in a separate terminal:

# Terminal 1
claude --worktree feature-auth

# Terminal 2
claude --worktree fix-payment-bug

# Terminal 3
claude --worktree refactor-database

The manual way: git worktree add

If you want more control over the directory location or branch name, create the worktree yourself:

# Create a worktree in a sibling directory with a new branch
git worktree add ../project-feature-auth -b feature-auth

# Navigate into it and start Claude
cd ../project-feature-auth
claude

You can also base the worktree on a specific commit or existing branch:

# Based on a specific branch
git worktree add ../hotfix-deploy release/v2.3

# Based on a specific commit
git worktree add ../investigate-bug abc1234

Resuming a previous session#

If you exit a worktree session and want to pick it back up later:

claude --resume feature-auth

This re-enters the same worktree directory and restores the Claude Code session context, including conversation history and any pending changes.

Working Inside a Worktree#

Once you're inside a worktree, everything works normally. Claude can:

  • Edit files
  • Run tests
  • Install dependencies
  • Make commits
  • Create branches
  • Run dev servers
  • Execute arbitrary commands

The key difference is that none of this affects your main working directory or any other worktree. Each session is fully isolated at the file system level.

Checking your worktree status#

From any worktree, you can see all active worktrees:

git worktree list

Example output:

/home/user/my-project                                   a1b2c3d [main]
/home/user/my-project/.claude/worktrees/feature-auth    d4e5f6g [worktree-feature-auth]
/home/user/my-project/.claude/worktrees/fix-payment-bug h7i8j9k [worktree-fix-payment-bug]

Commits and history#

Commits made in a worktree are immediately visible to all other worktrees because they share the same Git object store. If worktree A commits something on worktree-feature-auth, worktree B can git log worktree-feature-auth and see those commits right away (no fetch or push needed).

Managing Multiple Parallel Sessions#

Suggested workflow for parallel tasks#

  1. Identify independent tasks. Worktrees work best for tasks that touch different files or different areas of the codebase.
  2. Create one worktree per task. Give each a descriptive name.
  3. Let each Claude session focus on its task. Provide clear, scoped instructions.
  4. Merge each branch back to main when done.

Example: Three parallel sessions#

Terminal 1 — Auth feature
$ claude --worktree feature-auth
> "Implement OAuth2 login with Google provider. Add routes, middleware, and tests."

Terminal 2 — Payment bug
$ claude --worktree fix-payment-bug
> "Fix the double-charge bug in the Stripe webhook handler. Add a regression test."

Terminal 3 — Database refactor
$ claude --worktree refactor-database
> "Migrate the user table from MongoDB to PostgreSQL. Update all queries and models."

Each session runs independently. Auth doesn't interfere with payments. The database refactor doesn't break the auth flow mid-implementation.

Monitoring sessions#

You can check on any worktree's state from your main directory:

# See what branch each worktree is on
git worktree list

# See the commit log for a specific worktree's branch
git log --oneline worktree-feature-auth

# See uncommitted changes in a specific worktree
git -C .claude/worktrees/feature-auth status

Merging Work Back to Main#

Once a session is done and the code is working, you need to merge it back. There are three common approaches.

Option 1: Direct merge#

# Go back to your main working directory
cd /path/to/my-project
git checkout main

# Merge the worktree branch
git merge worktree-feature-auth

# If there are conflicts, resolve them, then:
git add .
git commit

Option 2: Create a pull request#

If your team uses code review:

# Push the worktree branch to the remote
git push origin worktree-feature-auth

# Create a PR using the GitHub CLI
gh pr create --base main --head worktree-feature-auth --title "Add OAuth2 login" --body "Implements Google OAuth2 provider with full test coverage."

Option 3: Ask Claude to do it#

Inside the worktree session, just tell Claude:

> Create a pull request for my changes with a detailed description.

Claude will push the branch and create the PR for you.

Handling merge conflicts#

If two worktrees touched overlapping files, you'll hit merge conflicts when merging back. This is the same as any Git merge conflict:

git merge worktree-feature-auth
# CONFLICT in src/middleware/auth.js

# Open the file, resolve the conflict markers, then:
git add src/middleware/auth.js
git commit

To minimize conflicts, try to scope worktree tasks to different areas of the codebase.

Cleanup and Maintenance#

Automatic cleanup#

When you exit a Claude Code worktree session:

  • No uncommitted changes? The worktree and its branch are deleted automatically.
  • Uncommitted changes exist? Claude prompts you to decide — commit, stash, or discard before cleanup.

Manual cleanup#

If you need to clean up a worktree yourself:

# Remove a specific worktree
git worktree remove .claude/worktrees/feature-auth

# Also delete the branch if you're done with it
git branch -D worktree-feature-auth

If a worktree directory was deleted without using git worktree remove (e.g., you just rm -rf the folder), Git will still track it. Clean up stale references with:

git worktree prune

Listing and auditing#

Periodically check for forgotten worktrees:

git worktree list

Worktrees that haven't been touched in a while are good candidates for cleanup. Each one holds disk space for its working copy.

Common Gotchas and How to Avoid Them#

1. Dependencies don't carry over#

Each worktree is a separate directory. If your project uses node_modules, venv, target/, or any locally installed dependencies, you need to install them in each worktree independently.

# In each new worktree:
npm install          # Node.js
pip install -r requirements.txt  # Python
bundle install       # Ruby
cargo build          # Rust

Claude Code will typically handle this when it starts working, but be aware of it if you're setting things up manually.

2. Shared ports and databases#

All worktrees run on the same machine. If two sessions try to start a dev server on port 3000, the second one will fail.

Solutions:

  • Use environment variables to set different ports per session:
    PORT=3001 npm run dev
    
  • Use different database names or schemas for sessions that run migrations:
    DATABASE_URL=postgres://localhost/myapp_worktree_auth npm run migrate
    
  • Tell Claude which port to use when starting the session:
    > Start the dev server on port 3001 to avoid conflicts with other sessions.
    

3. Same-file edits cause merge conflicts#

If worktree A and worktree B both edit src/config.ts, you'll get a merge conflict when merging both branches back to main. Plan your task scoping to minimize overlap.

4. Branch locking#

Git does not allow two worktrees to have the same branch checked out at the same time. If you try to create a second worktree on a branch that's already checked out, Git will refuse:

fatal: 'feature-auth' is already checked out at '/path/to/other/worktree'

This is by design — it prevents two worktrees from writing conflicting states to the same branch.

5. Large repos and disk space#

Each worktree creates a full copy of the working directory (but not the .git objects). For very large repos, having many worktrees can consume significant disk space. Monitor with:

du -sh .claude/worktrees/*

6. Submodules#

If your repo uses Git submodules, you may need to initialize them in each worktree:

cd .claude/worktrees/feature-auth
git submodule update --init --recursive

Real-World Example Workflow#

Here's a complete example of using worktrees to parallelize work on a web application.

Scenario#

You have three tasks to complete:

  1. Add a user profile page (frontend + API)
  2. Fix a bug where emails aren't sending (backend)
  3. Upgrade the testing framework from Jest to Vitest

These tasks are independent and touch different parts of the codebase.

Step 1: Spin up three sessions#

# Terminal 1
claude --worktree user-profile
> "Build a user profile page. Add a /profile route that shows the user's name,
   email, avatar, and account creation date. Include an API endpoint at
   GET /api/user/profile. Write tests for both the component and the endpoint."

# Terminal 2
claude --worktree fix-emails
> "Debug why transactional emails aren't being sent. Check the email service
   configuration, SMTP credentials, and the queue processor. Add logging and
   fix the issue. Write a test to prevent regression."

# Terminal 3
claude --worktree migrate-vitest
> "Migrate the test suite from Jest to Vitest. Update the config, fix any
   incompatible test syntax, and make sure all existing tests pass."

Step 2: Let Claude work in parallel#

Each session runs independently. You can monitor progress, answer questions, or let them work autonomously.

Step 3: Review and merge#

Once each session finishes:

# Create PRs for each
gh pr create --base main --head worktree-user-profile --title "Add user profile page"
gh pr create --base main --head worktree-fix-emails --title "Fix email sending"
gh pr create --base main --head worktree-migrate-vitest --title "Migrate to Vitest"

Review, approve, and merge each PR through your normal workflow.

Step 4: Clean up#

git worktree remove .claude/worktrees/user-profile
git worktree remove .claude/worktrees/fix-emails
git worktree remove .claude/worktrees/migrate-vitest

git branch -D worktree-user-profile worktree-fix-emails worktree-migrate-vitest

Quick Reference#

TaskCommand
Start a worktree sessionclaude --worktree <name>
Resume a previous sessionclaude --resume <name>
List all worktreesgit worktree list
Remove a worktreegit worktree remove .claude/worktrees/<name>
Delete the worktree branchgit branch -D worktree-<name>
Prune stale worktree referencesgit worktree prune
Merge a worktree branchgit checkout main && git merge worktree-<name>
Create a PR from a worktree branchgh pr create --base main --head worktree-<name>
Check worktree disk usagedu -sh .claude/worktrees/*
Initialize submodules in a worktreegit submodule update --init --recursive