Git Worktree — Simultaneous Branches Without Stashing Chaos
Stop stashing and switching.
20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.
- ✓Deep devops experience in a production environment
- ✓Familiarity with debugging, profiling, and performance analysis
- ✓Understanding of distributed systems and failure modes
git worktree add ../project-hotfix hotfix/bug creates a new directory with the hotfix branch checked out. git worktree list shows all worktrees. git worktree remove ../project-hotfix cleans up.
Imagine having the same book open to two different chapters at the same time on your desk. git worktree is like having two physical copies of the repo on your hard drive, but they share the same bookmark file (.git). You can work on a feature in one window and review a PR in another, without stashing or committing half-done work.
The standard Git workflow forces you to stash or commit before switching branches. git worktree removes this constraint entirely. Each worktree is a full working directory linked to the same .git database. You can build and test both branches simultaneously, switch between them instantly, and never lose context. The one constraint: a branch can only be checked out in one worktree at a time. This guide covers setup, the constraint that caught a team mid-deploy, and how to integrate worktrees into your daily workflow.
Setting Up and Managing Worktrees
git worktree add <path> <branch> creates a new worktree. If <branch> doesn't exist, add -b to create it. Each worktree has its own working directory, index, and HEAD. They share objects, refs, and config from the parent .git.
git worktree list shows all worktrees with their paths, branches, and commit SHAs. git worktree remove <path> (or git worktree prune) cleans up. Deleting the worktree directory manually requires git worktree prune to clean the metadata.
The key constraint: you cannot check out the same branch in two worktrees. If you try, Git rejects with 'fatal: '<branch>' is already checked out at '<other-path>''.
rm -rf a worktree directory without git worktree remove, the .git metadata remains. Future git worktree list shows a stale entry. Run git worktree prune to clean stale records. The worktree lock on the branch persists until you prune.git worktree prune before deploy to avoid stale lock conflicts.The Deploy That Failed Because a Branch Was Locked
git worktree add ../deploy-prep main to prepare a deployment. 2. They forgot to remove the worktree after finishing. 3. The branch 'main' was locked by the worktree — Git prevents writes to a branch that's checked out anywhere. 4. The CI pipeline's git fetch failed because it couldn't update the remote-tracking ref for main. 5. The error message ('refusing to fetch into checked out branch') was confusing because main wasn't checked out in the CI runner — it was checked out in the developer's worktree on a different machine.git worktree list on the developer's machine. 2. The worktree was stale (the directory had been deleted but Git didn't know). 3. Ran git worktree prune to remove stale worktree records. 4. Re-ran the CI pipeline successfully. 5. Added a pre-deploy CI check: git worktree list should show only the CI runner's worktree.- Worktrees lock branches.
- A branch can only be checked out in ONE worktree at a time.
- Always run
git worktree pruneregularly and clean up worktrees when done. - CI pipelines should check for stale locks before deploying.
git worktree add ../review-branch <branch-name> — creates a new directory with the PR branchgit worktree add ../hotfix -b hotfix/critical — starts a new branch in a separate directorygit worktree list then git worktree remove <path> for each one you don't needKey takeaways
git worktree prune20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.
That's Git. Mark it forged?
3 min read · try the examples if you haven't