GitWorktree.org logoGitWorktree.org

Monorepo Release Management with Worktrees

How a platform team maintains two active release branches and a development mainline — simultaneously — using git worktree.

The Problem

The Acme platform is a monorepo with 200+ packages. The team ships new features on main, while maintaining two long-lived release branches: release/v2 for enterprise customers still on v2, and release/v3 for the current stable release.

Every bug fix needs to land on main and then be cherry-picked to both release branches. Tests must pass on all three. Without worktrees, this means constant branch switching, rebuilding node_modules, and waiting for incremental builds to catch up — or maintaining three separate clones of a 4 GB repo.

The Worktree Setup

Instead of cloning three times, the team creates one clone and two linked worktrees:

One-time setup: create release worktrees
# Main worktree is the original clone on the main branch
cd ~/projects/acme          # already on main

# Create worktrees for each release branch
git worktree add ../acme-v2 release/v2
git worktree add ../acme-v3 release/v3

# Install dependencies in each
(cd ../acme-v2 && npm install) &
(cd ../acme-v3 && npm install) &
wait

The Git object database is shared, so this setup uses roughly 4 GB + working files instead of 12 GB for three full clones.

Daily Workflow

A typical bug fix flows through all three worktrees:

1. Fix the bug on main

Commit the fix on main
cd ~/projects/acme
# Fix the bug
git add -A && git commit -m "fix: prevent duplicate order events"
git push origin main

2. Cherry-pick to v3

Cherry-pick and test in the v3 worktree
cd ~/projects/acme-v3
git cherry-pick main
npm test                    # run tests against v3
git push origin release/v3

3. Cherry-pick to v2

Cherry-pick and test in the v2 worktree
cd ~/projects/acme-v2
git cherry-pick main
npm test                    # run tests against v2
git push origin release/v2

All three branches are updated and tested within minutes. There is no branch switching, no stashing, and no waiting for rebuilds — each worktree keeps its own build cache and node_modules.

Directory Structure

Three worktrees, one Git object store
~/projects/
├── acme/                    # main worktree — main branch
│   ├── .git/                # the actual Git repository (shared)
│   ├── packages/
│   ├── node_modules/
│   └── ...
│
├── acme-v3/                 # linked worktree — release/v3
│   ├── .git                 # file pointing to acme/.git
│   ├── packages/
│   ├── node_modules/        # v3-specific dependencies
│   └── ...
│
└── acme-v2/                 # linked worktree — release/v2
    ├── .git                 # file pointing to acme/.git
    ├── packages/
    ├── node_modules/        # v2-specific dependencies
    └── ...

Key Takeaways

  • Disk efficiency. The Git object database is stored once. Only the working files and build artifacts are duplicated per worktree.
  • Instant context switching. Switching between main, v3, and v2 is just a cd command. Each worktree has its own build state, so there is no rebuild penalty.
  • Parallel CI. You can run test suites in all three worktrees simultaneously. A bug fix that takes 10 minutes to test serially takes 4 minutes in parallel.
  • Long-lived worktrees are fine. Unlike feature worktrees that come and go, release worktrees can persist for months. Just keep them updated with git pull in each worktree.

You Might Also Like