Git Worktrees
Overview
Git worktrees enable checking out multiple branches simultaneously in separate directories, all sharing the same repository. Create a worktree instead of stashing changes or cloning separately.
Core principle: One worktree per active branch. Switch contexts by changing directories, not branches.
Core Concepts
Quick Reference
Essential Commands
Create a Worktree
List Worktrees
Example output:
Remove a Worktree
Move a Worktree
Lock/Unlock Worktrees
Prune Stale Worktrees
Repair Worktrees
Workflow Patterns
Pattern 1: Feature + Hotfix in Parallel
To fix a bug while feature work is in progress:
Pattern 2: PR Review While Working
To review a PR without affecting current work:
Pattern 3: Compare Implementations
To compare code across branches side-by-side:
Pattern 4: Long-Running Tasks
To run tests/builds in isolation while continuing development:
Pattern 5: Stable Reference
To maintain a clean main checkout for reference:
Pattern 6: Selective Merging from Multiple Features
To combine specific changes from multiple feature branches:
Comparing and Merging Changes Between Worktrees
Since all worktrees share the same Git repository, you can compare files, cherry-pick commits, and selectively merge changes between them.
Compare and Review File Changes
Since worktrees are just directories, you can compare files directly:
Merge Only One File from a Worktree
You can selectively bring a single file from another branch using git checkout:
For partial file changes (specific hunks/lines only):
This prompts you to accept/reject each change hunk individually with options:
y- apply this hunkn- skip this hunks- split into smaller hunkse- manually edit the hunk
Cherry-Pick Commits from Worktrees
Cherry-picking works at the commit level. Since all worktrees share the same repository, you can cherry-pick any commit:
Merge Changes from Multiple Worktrees
You can merge or cherry-pick from multiple branches:
Selective Merging - Pick Which Changes to Include
Option 1: Selective File Checkout
Option 2: Interactive Patch Selection
Option 3: Cherry-Pick with Selective Staging
Option 4: Merge with Manual Selection
Option 5: Using git restore (Git 2.23+)
Directory Structure Conventions
Organize worktrees predictably:
Naming convention: <project>-<purpose> or <project>-<branch>
Best Practices
Common Issues and Solutions
Issue: "Branch is already checked out"
Cause: Attempting to checkout a branch that's active in another worktree.
Solution:
Issue: Stale worktree after manual deletion
Cause: Deleted worktree directory without using git worktree remove.
Solution:
Issue: Worktree moved manually
Cause: Moved worktree directory without using git worktree move.
Solution:
Issue: Worktree on removed drive
Cause: Worktree was on removable storage that's no longer connected.
Solution:
Common Mistakes
Agent Workflow Integration
To isolate parallel agent tasks:
To experiment safely with detached HEAD:
Verification Checklist
Before using worktrees:
- Understand that branches can only be checked out in one worktree
- Know where worktrees will be created (use sibling directories)
- Plan cleanup strategy for temporary worktrees
When creating worktrees:
- Use descriptive directory names
- Verify branch is not already checked out elsewhere
- Consider using
--detachfor experiments
When removing worktrees:
- Commit or stash any uncommitted changes
- Use
git worktree remove, notrm -rf - Run
git worktree pruneif directory was deleted manually
How to Compare Worktrees
Workflow to compare files and directories between git worktrees, helping users understand differences in code across branches or worktrees.
Instructions
CRITICAL: Perform the following steps exactly as described:
-
Current state check: Run
git worktree listto show all existing worktrees and their locations -
Parse user input: Classify each provided argument:
- No arguments: Interactive mode - ask user what to compare
--stat: Show summary statistics of differences (files changed, insertions, deletions)- Worktree path: A path that matches one of the worktree roots from
git worktree list - Branch name: A name that matches a branch in one of the worktrees
- File/directory path: A path within the current worktree to compare
-
Determine comparison targets (worktrees to compare): a. If user provided worktree paths: Use those as comparison targets b. If user specified branch names: Find the worktrees for those branches from
git worktree listc. If only one worktree exists besides current: Use current and that one as comparison targets d. If multiple worktrees exist and none specified: Present list and ask user which to compare e. If no other worktrees exist: Offer to compare with a branch usinggit diff -
Determine what to compare (files/directories within worktrees): a. If user specified file(s) or directory(ies) paths: Compare ALL of them b. If no specific paths given: Ask user:
- "Compare entire worktree?" or
- "Compare specific files/directories? (enter paths)"
-
Execute comparison:
For specific files between worktrees:
For directories between worktrees:
For branch-level comparison (using git diff):
For comparing with current working directory:
-
Format and present results:
- Show clear header indicating what's being compared
- For large diffs, offer to show summary first
- Highlight significant changes (new files, deleted files, renamed files)
- Provide context about the branches each worktree contains
Comparison Modes
Worktree Detection
The command finds worktrees using git worktree list:
From this output, the command extracts:
- Path: The absolute path to the worktree directory
- Branch: The branch name in brackets (used when user specifies branch name)
Examples
Compare specific file between worktrees:
Compare between two specific worktrees:
Compare multiple files/directories:
Compare entire directories:
Get summary statistics:
Interactive mode:
Compare with branch worktree by branch name:
Compare specific paths between branch worktrees:
Output Format
File Comparison Header:
Summary Output:
Common Workflows
Review Feature Changes
Compare Implementations
Quick File Check
Pre-Merge Review
Important Notes
-
Argument detection: The command auto-detects argument types by comparing them against
git worktree listoutput:- Paths matching worktree roots → treated as worktrees to compare
- Names matching branches in worktrees → treated as worktrees to compare
- Other paths → treated as files/directories to compare within worktrees
-
Multiple paths: When multiple file/directory paths are provided, ALL of them are compared between the selected worktrees (not just the first one).
-
Worktree paths: When specifying worktrees, use the full path or relative path from current directory (e.g.,
../project-feature) -
Branch vs Worktree: If you specify a branch name, the command looks for a worktree with that branch checked out. If no worktree exists for that branch, it suggests using
git diffinstead. -
Large diffs: For large directories, the command will offer to show a summary first before displaying full diff output.
-
Binary files: Binary files are detected and reported as "Binary files differ" without showing actual diff.
-
File permissions: The diff will also show changes in file permissions if they differ.
-
No worktrees: If no other worktrees exist, the command will explain how to create one and offer to use
git difffor branch comparison instead.
Integration with Create Worktree
Use /worktrees create first to set up worktrees for comparison:
Troubleshooting
"No other worktrees found"
- Create a worktree first with
/worktrees create <branch> - Or use
git difffor branch-only comparison without worktrees
"Worktree for branch not found"
- The branch may not have a worktree created
- Run
git worktree listto see available worktrees - Create the worktree with
/worktrees create <branch>
"Path does not exist in worktree"
- The specified file/directory may not exist in one of the worktrees
- This could indicate the file was added/deleted in one branch
- The command will report this in the comparison output
How to Create Worktree
Workflow to create and setup git worktrees for parallel development, with automatic detection and installation of project dependencies.
Instructions
CRITICAL: Perform the following steps exactly as described:
-
Current state check: Run
git worktree listto show existing worktrees andgit statusto verify the repository state is clean (no uncommitted changes that might cause issues) -
Fetch latest remote branches: Run
git fetch --allto ensure local has knowledge of all remote branches -
Parse user input: Determine what the user wants to create:
<name>: Create worktree with auto-detected type prefix--list: Just show existing worktrees and exit- No input: Ask user interactively for the name
-
Auto-detect branch type from name: Check if the first word is a known branch type. If yes, use it as the prefix and the rest as the name. If no, default to
feature/.Known types:
feature,feat,fix,bug,bugfix,hotfix,release,docs,test,refactor,chore,spike,experiment,reviewExamples:
refactor auth system→refactor/auth-systemfix login bug→fix/login-bugauth system→feature/auth-system(default)hotfix critical error→hotfix/critical-error
Name normalization: Convert spaces to dashes, lowercase, remove special characters except dashes/underscores
-
For each worktree to create: a. Branch name construction: Build full branch name from detected type and normalized name:
<prefix>/<normalized-name>(e.g.,feature/auth-system)
b. Branch resolution: Determine if the branch exists locally, remotely, or needs to be created:
- If branch exists locally:
git worktree add ../<project>-<name> <branch> - If branch exists remotely (origin/<branch>):
git worktree add --track -b <branch> ../<project>-<name> origin/<branch> - If branch doesn't exist: Ask user for base branch (default: current branch or main/master), then
git worktree add -b <branch> ../<project>-<name> <base>
c. Path convention: Use sibling directory with pattern
../<project-name>-<name>- Extract project name from current directory
- Use the normalized name (NOT the full branch with prefix)
- Example:
feature/auth-system→../myproject-auth-system
d. Create the worktree: Execute the appropriate git worktree add command
e. Dependency detection: Check the new worktree for dependency files and determine if setup is needed:
package.json-> Node.js project (npm/yarn/pnpm/bun)requirements.txtorpyproject.tomlorsetup.py-> Python projectCargo.toml-> Rust projectgo.mod-> Go projectGemfile-> Ruby projectcomposer.json-> PHP project
f. Package manager detection (for Node.js projects):
bun.lockb-> Usebun installpnpm-lock.yaml-> Usepnpm installyarn.lock-> Useyarn installpackage-lock.jsonor default -> Usenpm install
g. Automatic setup: Automatically run dependency installation:
- cd to worktree and run the detected install command
- Report progress: "Installing dependencies with [package manager]..."
- If installation fails, report the error but continue with worktree creation summary
-
Summary: Display summary of created worktrees:
- Worktree path
- Branch name (full name with prefix)
- Setup status (dependencies installed or failed)
- Quick navigation command:
cd <worktree-path>
Worktree Path Convention
Worktrees are created as sibling directories to maintain organization:
Naming rules:
- Pattern:
<project-name>-<name>(uses the name part, NOT the full branch) - Branch name:
<type-prefix>/<name>(e.g.,feature/add-auth) - Directory name uses only the
<name>portion for brevity
Examples
Feature worktree (default):
Fix worktree:
Refactor worktree:
Hotfix worktree:
List existing worktrees:
Setup Detection Examples
Node.js project with pnpm:
Python project:
Rust project:
Common Workflows
Quick Feature Branch
Hotfix While Feature In Progress
PR Review Without Stashing
Experiment or Spike
Important Notes
-
Branch lock: Each branch can only be checked out in one worktree at a time. If a branch is already checked out, the command will inform you which worktree has it.
-
Shared .git: All worktrees share the same Git object database. Changes committed in any worktree are visible to all others.
-
Clean working directory: The command checks for uncommitted changes and warns if present, as creating worktrees is safest with a clean state.
-
Sibling directories: Worktrees are always created as sibling directories (using
../) to keep the workspace organized. Never create worktrees inside the main repository. -
Automatic dependency installation: The command automatically detects the project type and package manager, then runs the appropriate install command without prompting.
-
Remote tracking: For remote branches, worktrees are created with proper tracking setup (
--trackflag) so pulls/pushes work correctly.
Cleanup
When done with a worktree, use the proper removal command:
Or for a worktree with uncommitted changes:
Never use rm -rf to delete worktrees - always use git worktree remove.
Troubleshooting
"Branch is already checked out"
- Run
git worktree listto see where the branch is checked out - Either work in that worktree or remove it first
"Cannot create worktree - path already exists"
- The target directory already exists
- Either remove it or choose a different worktree path
"Dependency installation failed"
- Navigate to the worktree manually:
cd ../myproject-<name> - Run the install command directly to see full error output
- Common causes: missing system dependencies, network issues, corrupted lockfile
"Wrong type detected"
- The first word is used as the branch type if it's a known type
- To force a specific type, start with:
fix,hotfix,docs,test,refactor,chore,spike,review - Default type is
feature/when first word isn't a known type
How to Merge Worktree
Workflow to help users merge changes from git worktrees into their current branch, supporting multiple merge strategies from simple file checkout to selective cherry-picking.
Instructions
CRITICAL: Perform the following steps exactly as described:
-
Current state check: Run
git worktree listto show all existing worktrees andgit statusto verify working directory state -
Parse user input: Determine what merge operation the user wants:
--interactiveor no arguments: Guided interactive mode- File/directory path: Merge specific file(s) or directory from a worktree
- Commit name: Cherry-pick a specific commit
- Branch name: Merge from that branch's worktree
--from <worktree>: Specify source worktree explicitly--patchor-p: Use interactive patch selection mode
-
Determine source worktree/branch: a. If user specified
--from <worktree>: Use that worktree path directly b. If user specified a branch name: Find worktree for that branch fromgit worktree listc. If only one other worktree exists: Ask to confirm using it as source d. If multiple worktrees exist: Present list and ask user which to merge from e. If no other worktrees exist: Explain and offer to use branch-based merge instead -
Determine merge strategy: Present options based on user's needs:
Strategy A: Selective File Checkout (for specific files/directories)
- Best for: Getting complete file(s) from another branch
- Command:
git checkout <branch> -- <path>
Strategy B: Interactive Patch Selection (for partial file changes)
- Best for: Selecting specific hunks/lines from a file
- Command:
git checkout -p <branch> -- <path> - Prompts user for each hunk: y (apply), n (skip), s (split), e (edit)
Strategy C: Cherry-Pick with Selective Staging (for specific commits)
- Best for: Applying a commit but excluding some changes
- Steps:
git cherry-pick --no-commit <commit>- Review staged changes
git reset HEAD -- <unwanted-files>to unstagegit checkout -- <unwanted-files>to discardgit commit -m "message"
Strategy D: Manual Merge with Conflicts (for complex merges)
- Best for: Full branch merge with control over resolution
- Steps:
git merge --no-commit <branch>- Review all changes
- Selectively stage/unstage files
- Resolve conflicts if any
git commit -m "message"
Strategy E: Multi-Worktree Selective Merge (combining from multiple sources)
- Best for: Taking different files from different worktrees
- Steps:
git checkout <branch1> -- <path1>git checkout <branch2> -- <path2>git commit -m "Merge selected files from multiple branches"
-
Execute the selected strategy:
- Run pre-merge comparison if user wants to review (suggest
/worktrees comparefirst) - Execute git commands for the chosen strategy
- Handle any conflicts that arise
- Confirm changes before final commit
- Run pre-merge comparison if user wants to review (suggest
-
Post-merge summary: Display what was merged:
- Files changed/added/removed
- Source worktree/branch
- Merge strategy used
-
Cleanup prompt: After successful merge, ask:
- "Would you like to remove any worktrees to clean up local state?"
- If yes: List worktrees and ask which to remove
- Execute
git worktree remove <path>for selected worktrees - Remind about
git worktree pruneif needed
Merge Strategies Reference
Examples
Merge single file from worktree:
Interactive patch selection:
Cherry-pick specific commit:
Full guided mode:
Directory merge with conflicts:
Interactive Patch Mode Guide
When using --patch or Strategy B, the user sees prompts for each change hunk:
Cherry-Pick Selective Workflow
For Strategy C (cherry-picking with selective staging):
Multi-Worktree Merge Workflow
For Strategy E (merging from multiple worktrees):
Common Workflows
Take a Feature File Without Full Merge
Partial Bugfix from Hotfix Branch
Combine Multiple PRs' Changes
Pre-Merge Review
Important Notes
-
Working directory state: Always ensure your working directory is clean before merging. Uncommitted changes can cause conflicts.
-
Pre-merge review: Consider using
/worktrees comparebefore merging to understand what changes will be applied. -
Conflict resolution: If conflicts occur during merge, the command will help identify and resolve them before committing.
-
No-commit flag: Most strategies use
--no-committo give you control over the final commit message and what gets included. -
Shared repository: All worktrees share the same Git object database, so commits made in any worktree are immediately visible to cherry-pick from any other.
-
Branch locks: Remember that branches can only be checked out in one worktree at a time. Use branch names for merge operations rather than creating duplicate worktrees.
Cleanup After Merge
After merging, consider cleaning up worktrees that are no longer needed:
The command will prompt you about cleanup after each successful merge to help maintain a tidy workspace.
Troubleshooting
"Cannot merge: working directory has uncommitted changes"
- Commit or stash your current changes first
- Or use
git stashbefore merge,git stash popafter
"Merge conflict in <file>"
- The command will show conflicted files
- Open files and resolve conflicts (look for
<<<<<<<markers) - Stage resolved files with
git add <file> - Continue with
git commit
"Commit not found" when cherry-picking
- Ensure the commit hash is correct
- Run
git log <branch>in any worktree to find commits - Commits are shared across all worktrees
"Cannot checkout: file exists in working tree"
- File has local modifications
- Either commit, stash, or discard local changes first
- Then retry the merge operation
"Branch not found for worktree"
- The specified worktree may have been removed
- Run
git worktree listto see current worktrees - Use
git worktree pruneto clean up stale references
Integration with Other Commands
Pre-merge review:
Create worktree, merge, cleanup:


