If you work on a codebase that spans multiple repositories, you know the pain. A single ticket means changes in two, three, sometimes four repos at once. You’re constantly stashing, switching branches, losing context — or worse, maintaining duplicate clones that eat disk space and drift out of sync.
We hit this exact wall on our team. Our platform (Globe) has a layered architecture: shared modules feed into brand-specific repos. A typical feature ticket touches both the shared module and one or more brand repos simultaneously. The old workflow was brutal.
Then we adopted git worktrees with a central directory convention, and it changed everything.
What Are Git Worktrees?
A git worktree is a lightweight checkout linked to an existing clone. It shares the same .git object store — no duplication of history — but each worktree can be on its own branch independently.
Think of it as having multiple branches checked out at the same time, without cloning the repo again.
The Central Worktree Pattern
The key insight isn’t just using worktrees — it’s where you put them. Instead of scattering worktrees inside each repo, we use a central directory organized by ticket:
~/peopleinc/ # Main development directory
├── myrecipes/ # Primary clone (stays on default branch)
├── mm-myrecipes/ # Primary clone
├── globe-core/ # etc.
└── .worktrees/ # All worktrees live here
├── STAR-3485-quick-view-save-image/
│ ├── myrecipes/ # Worktree for this ticket
│ └── mm-myrecipes/
└── GLBE-12345-mantle-bump/
├── mantle/
└── myrecipes/
Every ticket gets a folder named {TICKET-ID}-{slug} (e.g., STAR-3485-quick-view-save-image). Inside, each repo you need for that ticket gets its own worktree. The feature branch follows the same stem: feature/STAR-3485-quick-view-save-image.
Why This Works So Well
1. Your primary clones stay clean. They sit on the default branch (master, main, release/X.Y) and never get feature work directly. No more “wait, which branch am I on?”
2. Ticket context is self-contained. Open ~/peopleinc/.worktrees/STAR-3485-quick-view-save-image/ in your IDE and you have everything for that ticket in one window. Multi-root workspaces in VS Code or Cursor make this seamless.
3. Parallel work is trivial. Working on two tickets? They’re in separate directories with separate branches. No stashing, no conflicts, no mental overhead.
4. The slug makes it scannable. STAR-3485 alone tells you nothing when you have 10 ticket folders. STAR-3485-quick-view-save-image tells you exactly what the work is.
5. Cleanup is straightforward. When a ticket’s PR merges, remove the worktrees and delete the folder:
git worktree remove ~/peopleinc/.worktrees/STAR-3485-quick-view-save-image/myrecipes
git worktree remove ~/peopleinc/.worktrees/STAR-3485-quick-view-save-image/mm-myrecipes
rmdir ~/peopleinc/.worktrees/STAR-3485-quick-view-save-image
Getting Started in 5 Minutes
Prerequisites: Your repos are cloned under a common root directory on their default branches.
Step 1: Create the central worktrees directory (one-time):
mkdir -p ~/peopleinc/.worktrees
Step 2: For each new ticket, create a folder and add worktrees:
export TICKET=STAR-3485
export SLUG=quick-view-save-image
export BRANCH=feature/${TICKET}-${SLUG}
export ROOT=~/peopleinc/.worktrees/${TICKET}-${SLUG}
mkdir -p ${ROOT}
# From each primary clone, create a worktree
cd ~/peopleinc/myrecipes
git fetch origin
git worktree add -b ${BRANCH} ${ROOT}/myrecipes origin/master
cd ~/peopleinc/mm-myrecipes
git worktree add -b ${BRANCH} ${ROOT}/mm-myrecipes origin/master
Step 3: Open ${ROOT} in your IDE and work normally. git add, git commit, git push — everything works as usual from inside the worktree.
If the branch already exists on the remote (e.g., a colleague started it), skip -b:
git worktree add ${ROOT}/myrecipes origin/${BRANCH}
Gotchas to Watch For
- Don’t check out the same branch in two worktrees of the same repo. Git won’t let you, and for good reason.
- Stash is shared across worktrees of the same repo. Name your stashes clearly if you use them.
- node_modules and build artifacts are per worktree. You’ll need to install and build in each one.
- Use
rmdir(notrm -rf) when cleaning up the ticket folder. If unexpected files are left behind, you want to know about it. - If you accidentally delete a worktree directory with
rm -rf, rungit worktree prunefrom the primary clone to clean up stale metadata.
Quick Reference
| Task | Command |
|---|---|
| List worktrees | git worktree list |
| New branch + worktree | git worktree add -b feature/TICKET-slug PATH BASE |
| Existing remote branch | git worktree add PATH origin/feature/TICKET-slug |
| Remove worktree | git worktree remove PATH |
| Clean stale metadata | git worktree prune |
The Bigger Picture
This pattern isn’t specific to our stack. Any team working across multiple repos — microservices, monorepo-adjacent setups, shared libraries with consuming apps — can benefit from central worktrees organized by ticket.
The convention is simple enough to adopt incrementally. Try it on your next multi-repo ticket and see if the mental overhead drops. For us, it did — dramatically.