{"slug": "git-worktrees-from-zero-to-hero-a-comprehensive-guide-to-using-git-worktrees", "title": "Git Worktrees: From Zero to Hero - A comprehensive guide to using Git worktrees with submodules", "summary": "Git worktrees allow developers to create multiple working directories from a single Git repository, enabling different branches to be checked out simultaneously without context switching. This solves the problem of having to stash or commit work before switching branches, as each worktree operates independently while sharing the same Git history. The article also covers how to use worktrees with submodules in monolith repositories, requiring separate initialization and management of each submodule across different worktrees.", "body_md": "# Git Worktrees: From Zero to Hero\n\n## Table of Contents\n1. [What Are Git Worktrees? (First Principles)](#what-are-git-worktrees-first-principles)\n2. [The Problem Worktrees Solve](#the-problem-worktrees-solve)\n3. [How Worktrees Work](#how-worktrees-work)\n4. [Worktrees + Submodules: Monolith Setup](#worktrees--submodules-monolith-setup)\n5. [Practical Tutorial: Creating Your First Worktree](#practical-tutorial-creating-your-first-worktree)\n6. [Advanced Workflows](#advanced-workflows)\n7. [Best Practices](#best-practices)\n8. [Troubleshooting](#troubleshooting)\n9. [For Non-Technical Stakeholders](#for-non-technical-stakeholders)\n\n---\n\n## What Are Git Worktrees? (First Principles)\n\n### The Traditional Git Model\nNormally, when you work with Git, you have:\n- **One working directory** (the folder with your code)\n- **One active branch** at a time\n- **Switching branches** changes all files in that directory\n\n```\nmy-project/\n├── src/\n├── README.md\n└── .git/\n```\n\nWhen you run `git checkout feature-branch`, ALL files change to match that branch.\n\n### The Worktree Model\nGit worktrees let you have:\n- **Multiple working directories** from the same repository\n- **Different branches** checked out simultaneously\n- **Independent work** in each directory\n\n```\nmy-project/                    ← Main repo (main branch)\n├── src/\n├── README.md\n└── .git/\n\nmy-project-feature-1/          ← Worktree 1 (feature-1 branch)\n├── src/\n├── README.md\n└── .git                      ← File pointing to main repo\n\nmy-project-feature-2/          ← Worktree 2 (feature-2 branch)\n├── src/\n├── README.md\n└── .git                      ← File pointing to main repo\n```\n\n### Key Insight\nThink of worktrees as **parallel universes** of your code:\n- Each universe (worktree) shows your project at a different point in time (branch/commit)\n- Changes in one universe don't affect the others\n- All universes share the same Git history (they're connected to the same `.git` repository)\n\n---\n\n## The Problem Worktrees Solve\n\n### Without Worktrees (Traditional Workflow)\n```bash\n# Working on feature A\ngit checkout feature-a\n# Make changes, test, etc.\n\n# Need to quickly check feature B\ngit stash                    # Save current work\ngit checkout feature-b       # Switch context\n# Look at feature B code\n\n# Back to feature A\ngit checkout feature-a\ngit stash pop               # Restore work\n# Continue where you left off\n```\n\n**Problems:**\n- Context switching overhead\n- Risk of losing uncommitted work\n- Can't compare branches side-by-side\n- Can't run tests on multiple branches simultaneously\n- Interrupts your flow\n\n### With Worktrees\n```bash\n# Create separate worktrees\ngit worktree add ../project-feature-a feature-a\ngit worktree add ../project-feature-b feature-b\n\n# Work in parallel\ncd ../project-feature-a     # Work on feature A\ncd ../project-feature-b     # Work on feature B (in another terminal)\n```\n\n**Benefits:**\n- No context switching\n- Work on multiple features simultaneously\n- Compare code side-by-side\n- Run different tests in parallel\n- Perfect for AI tools like Claude Code\n\n---\n\n## How Worktrees Work\n\n### The Git Magic\nWhen you create a worktree, Git:\n\n1. **Creates a new directory** with all your project files\n2. **Links it to the main repository** (shares Git history)\n3. **Checks out a specific branch** in that directory\n4. **Prevents conflicts** (same branch can't be checked out twice)\n\n### Under the Hood\n```\nmain-repo/\n└── .git/\n    ├── objects/           ← All Git data (shared)\n    ├── refs/              ← Branch references (shared)\n    └── worktrees/         ← Worktree metadata\n        ├── worktree-1/\n        └── worktree-2/\n\nworktree-1/\n├── your-files/            ← Working files (independent)\n└── .git                   ← File pointing to main-repo/.git\n\nworktree-2/\n├── your-files/            ← Working files (independent)\n└── .git                   ← File pointing to main-repo/.git\n```\n\n### The \"One Branch Per Worktree\" Rule\nGit prevents the same branch from being checked out in multiple worktrees:\n```bash\n# This works\ngit worktree add ../repo-feature-a feature-a\n\n# This fails if feature-a is already checked out\ngit worktree add ../repo-feature-a-copy feature-a\n# Error: 'feature-a' is already checked out\n```\n\nThis prevents confusion and conflicts.\n\n---\n\n## Worktrees + Submodules: Monolith Setup\n\n### What Makes This Setup Special\n\nA monolith repository can contain **multiple repositories as submodules**:\n```\nmonolith/\n├── frontend/              ← Git submodule (separate repo)\n├── backend/               ← Git submodule (separate repo)\n├── infrastructure/        ← Git submodule (separate repo)\n├── shared-components/     ← Git submodule (separate repo)\n└── .gitmodules           ← Submodule configuration\n```\n\n### The Challenge\nWhen you create a worktree of a repository with submodules:\n- The **main repository** gets a new worktree\n- The **submodules** need to be initialized separately\n- Each submodule can be on different branches in different worktrees\n\n### Automation Solution\nCreate automation scripts to handle this complexity:\n- [`create_worktree.py`](https://gist.github.com/ashwch/79177b4af7f2ea482418d6e9934d4787) - Creates worktrees with proper submodule setup\n- [`update_submodules.py`](https://gist.github.com/ashwch/909ea473250e8c8a937a8a4aa4a4dc72) - Manages submodule updates\n\n### Visual Example\n```\nmonolith/                                     ← Main repo (main branch)\n├── frontend/ (main branch)\n├── backend/ (main branch)\n└── infrastructure/ (main branch)\n\nmonolith-feature-123/                         ← Worktree (feature-123 branch)\n├── frontend/ (feature-123-frontend branch)\n├── backend/ (main branch)\n└── infrastructure/ (feature-123-infra branch)\n```\n\nNotice how:\n- Main repo worktree is on `feature-123` branch\n- Each submodule can be on different branches\n- This lets you work on related changes across multiple repositories\n\n---\n\n## Practical Tutorial: Creating Your First Worktree\n\n### Prerequisites\n```bash\n# Make sure you're in the main repository\ncd /path/to/your-monolith\n\n# Check current setup\ngit status\ngit worktree list\n```\n\n### Method 1: Using Automated Script (Recommended)\n\n```bash\n# Run smart worktree creation script\npython scripts/create_worktree.py\n# or with uv: uv run scripts/create_worktree.py\n```\n\n**What this script does:**\n1. **Asks for a worktree name** (suggests smart defaults)\n2. **Shows available branches** for main repo (with search)\n3. **For each submodule**, lets you choose which branch to use\n4. **Creates the worktree** one directory above current location\n5. **Initializes all submodules** with your chosen branches\n6. **Handles conflicts** gracefully\n\n**Example interaction:**\n```\nEnter worktree name (e.g., 'feature-auth'): feature-oauth\nCreating worktree: ../monolith-feature-oauth\n\nSelect branch for main repository:\n[1] main\n[2] feature/oauth-integration\n[3] develop\nChoice: 2\n\nSelect branch for frontend submodule:\n[1] main\n[2] feature/oauth-ui\n[3] develop\nChoice: 2\n\n... (continues for each submodule)\n\n✅ Worktree created successfully!\n📁 Location: ../monolith-feature-oauth\n🌳 Branch: feature/oauth-integration\n```\n\n### Method 2: Manual Creation (Educational)\n\n#### Step 1: Create the Basic Worktree\n```bash\n# Create worktree in parent directory\ngit worktree add ../monolith-feature-oauth feature/oauth-integration\n\n# Navigate to the new worktree\ncd ../monolith-feature-oauth\n```\n\n#### Step 2: Initialize Submodules\n```bash\n# Initialize all submodules (this takes time)\ngit submodule update --init --recursive\n\n# Check what branches submodules are on\ngit submodule foreach 'echo \"Submodule: $name, Branch: $(git branch --show-current)\"'\n```\n\n#### Step 3: Set Up Submodule Branches (Optional)\n```bash\n# Switch submodules to feature branches if needed\ncd frontend\ngit checkout feature/oauth-ui\ncd ../backend\ngit checkout main  # or whatever branch you need\ncd ../infrastructure\ngit checkout feature/oauth-config\ncd ..\n```\n\n### Verify Your Setup\n```bash\n# Check worktree status\ngit worktree list\n\n# Check branch in main repo\ngit branch --show-current\n\n# Check submodule branches\ngit submodule foreach 'echo \"$name: $(git branch --show-current)\"'\n```\n\n---\n\n## Advanced Workflows\n\n### Working Across Multiple Worktrees\n\n#### Scenario: Comparing Two Feature Implementations\n```bash\n# Create two worktrees for comparison\npython scripts/create_worktree.py  # Create approach-a\npython scripts/create_worktree.py  # Create approach-b\n\n# Work in parallel\ncd ../monolith-approach-a\n# Implement solution A\n\ncd ../monolith-approach-b  \n# Implement solution B\n\n# Compare side-by-side in your IDE\ncode ../monolith-approach-a ../monolith-approach-b\n```\n\n#### Scenario: AI-Assisted Development\n```bash\n# Create worktree for AI session\npython scripts/create_worktree.py\n\n# In the new worktree, run Claude Code\ncd ../monolith-feature-ai-assist\nclaude\n\n# Meanwhile, continue manual work in main repo\ncd /path/to/monolith\n# Continue your work without interruption\n```\n\n### Managing Submodule Changes\n\n#### Making Changes Across Multiple Repos\n```bash\n# In your worktree\ncd ../monolith-feature-123\n\n# Make changes in frontend\ncd frontend\ngit checkout -b feature-123-frontend\n# Make changes\ngit add . && git commit -m \"Frontend changes for feature 123\"\ngit push origin feature-123-frontend\n\n# Make changes in backend\ncd ../backend\ngit checkout -b feature-123-backend\n# Make changes\ngit add . && git commit -m \"Backend changes for feature 123\"\ngit push origin feature-123-backend\n\n# Update monolith to point to new commits\ncd ..\ngit add frontend backend\ngit commit -m \"Update submodules for feature 123\"\ngit push origin feature-123\n```\n\n#### Updating Submodules from Remote\n```bash\n# Use update script\npython scripts/update_submodules.py\n\n# Or manually\ngit submodule update --recursive --remote\n```\n\n### Cleaning Up Worktrees\n\n#### When Feature is Complete\n```bash\n# List all worktrees\ngit worktree list\n\n# Remove completed worktree\ngit worktree remove ../monolith-feature-123\n\n# Clean up any leftover references\ngit worktree prune\n```\n\n---\n\n## Best Practices\n\n### Naming Conventions\n```bash\n# Good worktree names\n../monolith-feature-auth           # Feature-based\n../monolith-bugfix-12345          # Issue-based\n../monolith-hotfix-critical       # Purpose-based\n../monolith-experiment-new-arch   # Experiment-based\n\n# Avoid\n../temp                           # Too generic\n../test                          # Unclear purpose\n../monolith                      # Confusing with main\n```\n\n### Directory Organization\n```bash\n# Recommended structure\nprojects/\n├── monolith/                    ← Main repository\n├── monolith-feature-auth/       ← Feature worktree\n├── monolith-feature-payments/   ← Another feature\n└── monolith-hotfix-urgent/      ← Hotfix worktree\n```\n\n### Branch Strategy\n```bash\n# Main repository branches\nmain                             ← Production\ndevelop                          ← Integration\nfeature/auth-system             ← Feature branch\nhotfix/critical-bug             ← Hotfix branch\n\n# Submodule branches (can be independent)\nfrontend: feature/auth-ui\nbackend: feature/auth-api\ninfrastructure: main            ← Unchanged for this feature\n```\n\n### Workflow Tips\n\n#### 1. One Worktree Per Feature\n- Don't reuse worktrees for different features\n- Create new worktrees for each major task\n- Clean up when done\n\n#### 2. Initialize Submodules Immediately\n```bash\n# Always run after creating worktree\ngit submodule update --init --recursive\n```\n\n#### 3. Use Automation Scripts\n```bash\n# Let automation handle complexity\npython create_worktree.py  # Download from: https://gist.github.com/ashwch/79177b4af7f2ea482418d6e9934d4787\npython update_submodules.py # Download from: https://gist.github.com/ashwch/909ea473250e8c8a937a8a4aa4a4dc72\n```\n\n#### 4. Regular Cleanup\n```bash\n# Weekly cleanup of old worktrees\ngit worktree list\ngit worktree remove ../old-worktree-name\ngit worktree prune\n```\n\n---\n\n## Troubleshooting\n\n### Common Issues and Solutions\n\n#### Issue: \"Branch is already checked out\"\n```bash\n# Error when trying to create worktree\nfatal: 'main' is already checked out at '/path/to/monolith'\n\n# Solution: Use a different branch or create new branch\ngit worktree add ../monolith-new -b new-branch-name main\n```\n\n#### Issue: Submodules Not Initialized\n```bash\n# Symptoms: Empty submodule directories\nls frontend/  # Empty\n\n# Solution: Initialize submodules\ngit submodule update --init --recursive\n```\n\n#### Issue: Submodule in Wrong Branch\n```bash\n# Check current branches\ngit submodule foreach 'echo \"$name: $(git branch --show-current)\"'\n\n# Fix: Switch to correct branch\ncd problematic-submodule\ngit checkout correct-branch\ncd ..\n```\n\n#### Issue: Can't Remove Worktree\n```bash\n# Error: worktree contains modified or untracked files\ngit worktree remove ../old-worktree\n\n# Solution: Force removal (loses uncommitted changes!)\ngit worktree remove --force ../old-worktree\n```\n\n#### Issue: Submodule Conflicts During Merge\n```bash\n# When merging between branches with different submodule commits\n# Solution: Choose which submodule commits to keep\ngit add problematic-submodule\ngit commit -m \"Resolve submodule conflicts\"\n```\n\n### Performance Tips\n\n#### Large Repository Optimization\n```bash\n# Speed up submodule operations\ngit config submodule.recurse true\ngit config diff.submodule log\ngit config status.submodulesummary 1\n```\n\n#### Disk Space Management\n```bash\n# Share objects between worktrees (done automatically)\n# But be aware: multiple worktrees = multiple working copies\n\n# Check disk usage\ndu -sh ../monolith*\n```\n\n---\n\n## For Non-Technical Stakeholders\n\n### What This Means for You\n\n#### The Problem We Solved\nImagine you're writing a document and need to:\n- Work on Chapter 1 revisions\n- Also draft Chapter 5\n- Compare two different approaches for Chapter 3\n\nTraditionally, you'd have to:\n1. Save Chapter 1 work\n2. Switch to Chapter 5\n3. Save Chapter 5 work\n4. Switch to Chapter 3\n5. Go back and forth constantly\n\nThis is inefficient and error-prone.\n\n#### Our Solution: Git Worktrees\nNow we can have:\n- **Document-v1/** folder for Chapter 1 work\n- **Document-v2/** folder for Chapter 5 work  \n- **Document-experiment/** folder for Chapter 3 approaches\n\nAll folders stay synchronized with the main document, but you can work on different parts independently.\n\n### Business Benefits\n\n#### 1. Faster Development\n- **No context switching delays** - developers stay in flow\n- **Parallel development** - multiple features simultaneously\n- **Reduced merge conflicts** - isolated work streams\n\n#### 2. Better Quality\n- **Side-by-side comparisons** - easy to evaluate approaches\n- **Isolated testing** - test features without affecting others\n- **Safer experimentation** - try ideas without risk\n\n#### 3. Enhanced Collaboration\n- **AI tools work better** - can analyze multiple implementations\n- **Code reviews easier** - compare implementations directly\n- **Knowledge sharing** - team members can see different approaches\n\n### Impact on Project Timelines\n\n#### Before Worktrees\n```\nWeek 1: Start Feature A\nWeek 2: Urgent bug interrupt → Switch context → Fix bug\nWeek 3: Return to Feature A → Re-understand code → Continue\nWeek 4: Complete Feature A\n```\n**Total: 4 weeks for Feature A + 1 bug fix**\n\n#### With Worktrees\n```\nWeek 1: Start Feature A (main worktree)\nWeek 2: Urgent bug → Create hotfix worktree → Fix bug in parallel\nWeek 3: Complete Feature A (uninterrupted) + Complete bug fix\nWeek 4: Start Feature B\n```\n**Total: 3 weeks for Feature A + 1 bug fix + start Feature B**\n\n### What You'll Notice\n\n#### As a Product Manager\n- **Faster feature delivery** - less time lost to context switching\n- **Better estimations** - developers can work more predictably\n- **Easier demonstrations** - can show multiple versions side-by-side\n\n#### As a Designer\n- **Quick iterations** - developers can implement multiple design approaches\n- **Live comparisons** - see different implementations running simultaneously\n- **Faster feedback loops** - no delay switching between versions\n\n#### As a Stakeholder\n- **More reliable timelines** - fewer interruptions and delays\n- **Higher quality output** - easier to compare and choose best solutions\n- **Reduced risk** - experiments don't affect main development\n\n---\n\n## Summary\n\nGit worktrees with submodules give us superpowers:\n\n1. **Multiple parallel universes** of our codebase\n2. **No context switching** between features\n3. **AI tools work better** with isolated environments\n4. **Complex projects simplified** through automation\n5. **Team productivity increased** through better workflows\n\n### Key Commands to Remember\n```bash\n# Create worktree (automated)\npython scripts/create_worktree.py\n\n# List worktrees\ngit worktree list\n\n# Remove worktree\ngit worktree remove ../worktree-name\n\n# Update submodules\npython scripts/update_submodules.py\n```\n\n### Next Steps\n1. Try creating your first worktree with our script\n2. Experiment with parallel development\n3. Use worktrees for your next feature\n4. Share this guide with your team\n5. Contribute improvements to automation scripts\n\n---\n\n*This guide covers Git worktrees with submodules for modern development workflows. Questions? Contributions welcome!*", "url": "https://wpnews.pro/news/git-worktrees-from-zero-to-hero-a-comprehensive-guide-to-using-git-worktrees", "canonical_source": "https://gist.github.com/ashwch/946ad983977c9107db7ee9abafeb95bd", "published_at": "2025-08-07 05:32:31+00:00", "updated_at": "2026-05-22 15:09:58.050049+00:00", "lang": "en", "topics": ["developer-tools", "open-source"], "entities": ["Git"], "alternates": {"html": "https://wpnews.pro/news/git-worktrees-from-zero-to-hero-a-comprehensive-guide-to-using-git-worktrees", "markdown": "https://wpnews.pro/news/git-worktrees-from-zero-to-hero-a-comprehensive-guide-to-using-git-worktrees.md", "text": "https://wpnews.pro/news/git-worktrees-from-zero-to-hero-a-comprehensive-guide-to-using-git-worktrees.txt", "jsonld": "https://wpnews.pro/news/git-worktrees-from-zero-to-hero-a-comprehensive-guide-to-using-git-worktrees.jsonld"}}