Table of Contents #
- What Are Git Worktrees? (First Principles)
- The Problem Worktrees Solve
- How Worktrees Work
- Worktrees + Submodules: Monolith Setup
- Practical Tutorial: Creating Your First Worktree
- Advanced Workflows
- Best Practices
- Troubleshooting
- For Non-Technical Stakeholders
What Are Git Worktrees? (First Principles) #
The Traditional Git Model
Normally, when you work with Git, you have:
- One working directory (the folder with your code)
- One active branch at a time
- Switching branches changes all files in that directory
my-project/
โโโ src/
โโโ README.md
โโโ .git/
When you run git checkout feature-branch, ALL files change to match that branch.
The Worktree Model
Git worktrees let you have:
- Multiple working directories from the same repository
- Different branches checked out simultaneously
- Independent work in each directory
my-project/ โ Main repo (main branch)
โโโ src/
โโโ README.md
โโโ .git/
my-project-feature-1/ โ Worktree 1 (feature-1 branch)
โโโ src/
โโโ README.md
โโโ .git โ File pointing to main repo
my-project-feature-2/ โ Worktree 2 (feature-2 branch)
โโโ src/
โโโ README.md
โโโ .git โ File pointing to main repo
Key Insight
Think of worktrees as parallel universes of your code:
- Each universe (worktree) shows your project at a different point in time (branch/commit)
- Changes in one universe don't affect the others
- All universes share the same Git history (they're connected to the same
.gitrepository)
The Problem Worktrees Solve #
Without Worktrees (Traditional Workflow)
git checkout feature-a
git stash # Save current work
git checkout feature-b # Switch context
git checkout feature-a
git stash pop # Restore work
Problems:
- Context switching overhead
- Risk of losing uncommitted work
- Can't compare branches side-by-side
- Can't run tests on multiple branches simultaneously
- Interrupts your flow
With Worktrees
git worktree add ../project-feature-a feature-a
git worktree add ../project-feature-b feature-b
cd ../project-feature-a # Work on feature A
cd ../project-feature-b # Work on feature B (in another terminal)
Benefits:
- No context switching
- Work on multiple features simultaneously
- Compare code side-by-side
- Run different tests in parallel
- Perfect for AI tools like Claude Code
How Worktrees Work #
The Git Magic
When you create a worktree, Git:
- Creates a new directory with all your project files
- Links it to the main repository (shares Git history)
- Checks out a specific branch in that directory
- Prevents conflicts (same branch can't be checked out twice)
Under the Hood
main-repo/
โโโ .git/
โโโ objects/ โ All Git data (shared)
โโโ refs/ โ Branch references (shared)
โโโ worktrees/ โ Worktree metadata
โโโ worktree-1/
โโโ worktree-2/
worktree-1/
โโโ your-files/ โ Working files (independent)
โโโ .git โ File pointing to main-repo/.git
worktree-2/
โโโ your-files/ โ Working files (independent)
โโโ .git โ File pointing to main-repo/.git
The "One Branch Per Worktree" Rule
Git prevents the same branch from being checked out in multiple worktrees:
git worktree add ../repo-feature-a feature-a
git worktree add ../repo-feature-a-copy feature-a
This prevents confusion and conflicts.
Worktrees + Submodules: Monolith Setup #
What Makes This Setup Special
A monolith repository can contain multiple repositories as submodules:
monolith/
โโโ frontend/ โ Git submodule (separate repo)
โโโ backend/ โ Git submodule (separate repo)
โโโ infrastructure/ โ Git submodule (separate repo)
โโโ shared-components/ โ Git submodule (separate repo)
โโโ .gitmodules โ Submodule configuration
The Challenge
When you create a worktree of a repository with submodules:
- The main repository gets a new worktree
- The submodules need to be initialized separately
- Each submodule can be on different branches in different worktrees
Automation Solution
Create automation scripts to handle this complexity:
create_worktree.py- Creates worktrees with proper submodule setupupdate_submodules.py- Manages submodule updates
Visual Example
monolith/ โ Main repo (main branch)
โโโ frontend/ (main branch)
โโโ backend/ (main branch)
โโโ infrastructure/ (main branch)
monolith-feature-123/ โ Worktree (feature-123 branch)
โโโ frontend/ (feature-123-frontend branch)
โโโ backend/ (main branch)
โโโ infrastructure/ (feature-123-infra branch)
Notice how:
- Main repo worktree is on
feature-123branch - Each submodule can be on different branches
- This lets you work on related changes across multiple repositories
Practical Tutorial: Creating Your First Worktree #
Prerequisites
cd /path/to/your-monolith
git status
git worktree list
Method 1: Using Automated Script (Recommended)
python scripts/create_worktree.py
What this script does:
- Asks for a worktree name (suggests smart defaults)
- Shows available branches for main repo (with search)
- For each submodule, lets you choose which branch to use
- Creates the worktree one directory above current location
- Initializes all submodules with your chosen branches
- Handles conflicts gracefully
Example interaction:
Enter worktree name (e.g., 'feature-auth'): feature-oauth
Creating worktree: ../monolith-feature-oauth
Select branch for main repository:
[1] main
[2] feature/oauth-integration
[3] develop
Choice: 2
Select branch for frontend submodule:
[1] main
[2] feature/oauth-ui
[3] develop
Choice: 2
... (continues for each submodule)
โ
Worktree created successfully!
๐ Location: ../monolith-feature-oauth
๐ณ Branch: feature/oauth-integration
Method 2: Manual Creation (Educational)
Step 1: Create the Basic Worktree
git worktree add ../monolith-feature-oauth feature/oauth-integration
cd ../monolith-feature-oauth
Step 2: Initialize Submodules
git submodule update --init --recursive
git submodule foreach 'echo "Submodule: $name, Branch: $(git branch --show-current)"'
Step 3: Set Up Submodule Branches (Optional)
cd frontend
git checkout feature/oauth-ui
cd ../backend
git checkout main # or whatever branch you need
cd ../infrastructure
git checkout feature/oauth-config
cd ..
Verify Your Setup
git worktree list
git branch --show-current
git submodule foreach 'echo "$name: $(git branch --show-current)"'
Advanced Workflows #
Working Across Multiple Worktrees
Scenario: Comparing Two Feature Implementations
python scripts/create_worktree.py # Create approach-a
python scripts/create_worktree.py # Create approach-b
cd ../monolith-approach-a
cd ../monolith-approach-b
code ../monolith-approach-a ../monolith-approach-b
Scenario: AI-Assisted Development
python scripts/create_worktree.py
cd ../monolith-feature-ai-assist
claude
cd /path/to/monolith
Managing Submodule Changes
Making Changes Across Multiple Repos
cd ../monolith-feature-123
cd frontend
git checkout -b feature-123-frontend
git add . && git commit -m "Frontend changes for feature 123"
git push origin feature-123-frontend
cd ../backend
git checkout -b feature-123-backend
git add . && git commit -m "Backend changes for feature 123"
git push origin feature-123-backend
cd ..
git add frontend backend
git commit -m "Update submodules for feature 123"
git push origin feature-123
Updating Submodules from Remote
python scripts/update_submodules.py
git submodule update --recursive --remote
Cleaning Up Worktrees
When Feature is Complete
git worktree list
git worktree remove ../monolith-feature-123
git worktree prune
Best Practices #
Naming Conventions
../monolith-feature-auth # Feature-based
../monolith-bugfix-12345 # Issue-based
../monolith-hotfix-critical # Purpose-based
../monolith-experiment-new-arch # Experiment-based
../temp # Too generic
../test # Unclear purpose
../monolith # Confusing with main
Directory Organization
projects/
โโโ monolith/ โ Main repository
โโโ monolith-feature-auth/ โ Feature worktree
โโโ monolith-feature-payments/ โ Another feature
โโโ monolith-hotfix-urgent/ โ Hotfix worktree
Branch Strategy
main โ Production
develop โ Integration
feature/auth-system โ Feature branch
hotfix/critical-bug โ Hotfix branch
frontend: feature/auth-ui
backend: feature/auth-api
infrastructure: main โ Unchanged for this feature
Workflow Tips
1. One Worktree Per Feature
- Don't reuse worktrees for different features
- Create new worktrees for each major task
- Clean up when done
2. Initialize Submodules Immediately
git submodule update --init --recursive
3. Use Automation Scripts
python create_worktree.py # Download from: https://gist.github.com/ashwch/79177b4af7f2ea482418d6e9934d4787
python update_submodules.py # Download from: https://gist.github.com/ashwch/909ea473250e8c8a937a8a4aa4a4dc72
4. Regular Cleanup
git worktree list
git worktree remove ../old-worktree-name
git worktree prune
Troubleshooting #
Common Issues and Solutions
Issue: "Branch is already checked out"
fatal: 'main' is already checked out at '/path/to/monolith'
git worktree add ../monolith-new -b new-branch-name main
Issue: Submodules Not Initialized
ls frontend/ # Empty
git submodule update --init --recursive
Issue: Submodule in Wrong Branch
git submodule foreach 'echo "$name: $(git branch --show-current)"'
cd problematic-submodule
git checkout correct-branch
cd ..
Issue: Can't Remove Worktree
git worktree remove ../old-worktree
git worktree remove --force ../old-worktree
Issue: Submodule Conflicts During Merge
git add problematic-submodule
git commit -m "Resolve submodule conflicts"
Performance Tips
Large Repository Optimization
git config submodule.recurse true
git config diff.submodule log
git config status.submodulesummary 1
Disk Space Management
du -sh ../monolith*
For Non-Technical Stakeholders #
What This Means for You
The Problem We Solved
Imagine you're writing a document and need to:
- Work on Chapter 1 revisions
- Also draft Chapter 5
- Compare two different approaches for Chapter 3
Traditionally, you'd have to:
- Save Chapter 1 work
- Switch to Chapter 5
- Save Chapter 5 work
- Switch to Chapter 3
- Go back and forth constantly
This is inefficient and error-prone.
Our Solution: Git Worktrees
Now we can have:
- Document-v1/ folder for Chapter 1 work
- Document-v2/ folder for Chapter 5 work
- Document-experiment/ folder for Chapter 3 approaches
All folders stay synchronized with the main document, but you can work on different parts independently.
Business Benefits
1. Faster Development
- No context switching delays - developers stay in flow
- Parallel development - multiple features simultaneously
- Reduced merge conflicts - isolated work streams
2. Better Quality
- Side-by-side comparisons - easy to evaluate approaches
- Isolated testing - test features without affecting others
- Safer experimentation - try ideas without risk
3. Enhanced Collaboration
- AI tools work better - can analyze multiple implementations
- Code reviews easier - compare implementations directly
- Knowledge sharing - team members can see different approaches
Impact on Project Timelines
Before Worktrees
Week 1: Start Feature A
Week 2: Urgent bug interrupt โ Switch context โ Fix bug
Week 3: Return to Feature A โ Re-understand code โ Continue
Week 4: Complete Feature A
Total: 4 weeks for Feature A + 1 bug fix
With Worktrees
Week 1: Start Feature A (main worktree)
Week 2: Urgent bug โ Create hotfix worktree โ Fix bug in parallel
Week 3: Complete Feature A (uninterrupted) + Complete bug fix
Week 4: Start Feature B
Total: 3 weeks for Feature A + 1 bug fix + start Feature B
What You'll Notice
As a Product Manager
- Faster feature delivery - less time lost to context switching
- Better estimations - developers can work more predictably
- Easier demonstrations - can show multiple versions side-by-side
As a Designer
- Quick iterations - developers can implement multiple design approaches
- Live comparisons - see different implementations running simultaneously
- Faster feedback loops - no delay switching between versions
As a Stakeholder
- More reliable timelines - fewer interruptions and delays
- Higher quality output - easier to compare and choose best solutions
- Reduced risk - experiments don't affect main development
Summary #
Git worktrees with submodules give us superpowers:
- Multiple parallel universes of our codebase
- No context switching between features
- AI tools work better with isolated environments
- Complex projects simplified through automation
- Team productivity increased through better workflows
Key Commands to Remember
python scripts/create_worktree.py
git worktree list
git worktree remove ../worktree-name
python scripts/update_submodules.py
Next Steps
- Try creating your first worktree with our script
- Experiment with parallel development
- Use worktrees for your next feature
- Share this guide with your team
- Contribute improvements to automation scripts
This guide covers Git worktrees with submodules for modern development workflows. Questions? Contributions welcome!