Git Worktree Examples
Practical, copy-paste examples for the day-to-day worktree workflow: creating, checking out, merging, fetching, and tearing down. All commands assume a recent Git (2.23+) so git switch works alongside the older git checkout.
Recipe
Quick-reference recipe card -- copy-paste ready.
# Create + checkout an existing branch in a new worktree
git worktree add ../feature-branch feature-branch
# Create a new branch and check it out in a new worktree
git worktree add ../new-feature -b new-feature
# Detached HEAD on a specific commit or tag
git worktree add ../hotfix abc1234
# List worktrees and the branch each one has checked out
git worktree list
# Remove a worktree once you're done
git worktree remove ../feature-branch
# Clean up stale entries after a folder was deleted manually
git worktree pruneWhen to reach for this: Any worktree-driven workflow -- feature dev, hotfix isolation, PR review, side-by-side comparison.
Working Example
Full feature lifecycle
# 1. Start the feature in a new worktree on a new branch
git worktree add ../my-feature -b my-feature
# 2. Move into it and work normally
cd ../my-feature
# ...edit files, run tests, commit...
git add .
git commit -m "feat: scaffold my-feature"
# 3. Walk back to main and merge
cd ../main-repo
git switch main
git pull origin main
git merge my-feature
# 4. Push and clean up
git push origin main
git worktree remove ../my-feature
git branch -d my-featureWhat this demonstrates:
- Worktrees and branches share history immediately -- no push/pull cycle needed between them.
- Merging happens in the target worktree (the one whose branch will receive the changes).
- Removing a worktree leaves the branch intact; deleting the branch is a separate, deliberate step.
Deep Dive
1. Creating and checking out branches in worktrees
The core commands -- start here.
# Create a new worktree and checkout an existing branch
git worktree add ../feature-branch feature-branch
# Create a new branch AND check it out in a new worktree
git worktree add ../new-feature -b new-feature
# Checkout a specific commit or tag (detached HEAD)
git worktree add ../hotfix abc1234
# Modern alternative to git checkout (safer for branches)
git switch <branch> # Inside a worktree
git switch -c <new-branch> # Create + switchTip: Prefer git switch over git checkout for branch operations (introduced in Git 2.23+). git checkout still works but is overloaded with file-restore behavior, which is a foot-gun when you mistype a branch name.
2. Listing and managing branches across worktrees
git branch -a # All branches (local + remote)
git branch -v # With last commit info
git worktree list # Which branch each worktree has checked out
git worktree list --porcelain # Machine-readable for scriptsgit worktree list is the answer to "wait, where did I leave that hotfix?"
3. Merging branches across worktrees (common workflow)
Merging happens in the target worktree -- usually the one with main or a release branch checked out.
# From your main worktree:
cd ../main-project
git switch main # or: git checkout main
git pull origin main # Always update first
# Merge a completed feature branch (developed in another worktree)
git merge feature-branch # Fast-forward or create a merge commit
# Merge with options
git merge --no-ff feature-branch # Always create a merge commit
git merge --squash feature-branch # Squash changes (then commit manually)
# Rebase instead, for a cleaner history
git switch feature-branch # Switch into the feature branch's worktree first
git rebase main
git switch main
git merge feature-branch # Now a clean fast-forwardCross-worktree merge example:
- Finish work and commit inside
../feature-worktree. cdback to the main worktree.git merge feature-branch-- the branch pointer was updated automatically by the commit in the other worktree.
No push, no pull, no remote round-trip. The shared .git folder makes this seamless.
4. Fetching, pulling, and updating
git fetch origin # Updates remote refs -- visible from all worktrees
git pull origin main # Fetch + merge into the worktree you ran this in
# Update a feature worktree's base
cd ../my-feature
git fetch origin
git rebase origin/main # Replay your feature commits on top of latest mainKey point: git fetch updates state in the shared .git folder, so every worktree sees the new remote refs immediately. git pull only affects the branch checked out in the worktree where you ran it.
5. Other useful checkout/merge-related commands
Cherry-pick a commit from another branch or worktree:
git cherry-pick abc1234Compare branches without switching:
git diff main..feature-branchResolve conflicts during a merge (standard flow):
git status # See conflicted files
# Edit each file to resolve markers
git add <file>
git merge --continueAbort a merge:
git merge --abortFor the full conflict-resolution playbook, see Merge Conflict Resolution Checklist.
6. Full lifecycle example
# 1. Start feature
git worktree add ../my-feature -b my-feature
# 2. Work and commit in that directory...
cd ../my-feature
# ...code, test, commit...
# 3. Merge back
cd ../main-repo
git switch main
git merge my-feature
# 4. Clean up
git worktree remove ../my-feature
git branch -d my-feature # Optional: delete branch7. Hotfix interrupts in-progress feature
# You're deep in feature work in ../my-feature, and prod breaks.
# Don't stash. Don't switch branches. Just spin up a hotfix worktree.
cd ~/projects/main-repo
git fetch origin
git worktree add ../hotfix -b hotfix/login-500 origin/main
cd ../hotfix
# ...debug, fix, commit, push, open PR...
git push -u origin hotfix/login-500
# Once the PR is merged, clean up
cd ~/projects/main-repo
git worktree remove ../hotfix
git branch -D hotfix/login-500 # If the remote branch was deleted on merge
# Walk back to your feature work, exactly as you left it
cd ../my-feature8. PR review without disturbing your work
# A teammate pushed a branch you need to review
git fetch origin
git worktree add ../review-pr-482 origin/feature/teammate-thing
cd ../review-pr-482
npm install
npm run dev
# ...read code, test it, leave PR comments...
# Tear it down when done
cd ../main-repo
git worktree remove ../review-pr-4829. Side-by-side comparison
# Run two implementations at once for a real comparison
git worktree add ../approach-a -b experiment/approach-a
git worktree add ../approach-b -b experiment/approach-b
# Two terminal windows, two dev servers on different ports, both editable.
# When done, keep the winner, remove the loser.
git worktree remove ../approach-b
git branch -D experiment/approach-bPro tips & pitfalls
- Always commit or stash changes before removing a worktree. Git refuses by default; use
--forceonly when you're certain. - Run
git worktree pruneafter manually deleting a worktree directory. git fetchonce, see updates everywhere -- the shared.gitfolder makes refs instantly visible across all worktrees.- For complex merges, consider
git mergetool-- it works the same in any worktree. - Submodules need
git submodule update --init --recursiveper worktree.
Gotchas
Things that will bite you. Each gotcha includes what goes wrong, why it happens, and the fix.
-
fatal: '<branch>' is already checked out at ...-- You tried to add a worktree on a branch that's checked out elsewhere. Fix: Either work in the existing worktree, or branch off:git worktree add ../scratch -b scratch <branch>. -
Rebase conflicts in a feature worktree, then forgetting to update the merge target -- You rebased
featureontoorigin/maininside../my-feature, but in your main worktree you forgot togit pullfirst. Fix: Alwaysgit fetch+git pullin the target worktree before merging. -
git checkout <branch>switches files in the current worktree -- You meant to add a worktree but typed the old command. Fix: Usegit worktree addto create a new worktree;git switch/git checkoutonly changes the current one. -
Stashes apply across worktrees and surprise you -- You stashed in worktree A, then
git stash popin worktree B applies the wrong files. Fix: Stashes are shared. Name them (git stash push -m "feature X wip") and review withgit stash listbefore popping. -
Force-pushing a branch from one worktree breaks merges in another -- Worktree A force-pushes
feature, worktree B still has the old commits checked out and agit pulltriggers a confusing fast-forward refusal. Fix: Coordinate force-pushes; rerungit fetch+git reset --hard origin/featurein the other worktree if you're certain. -
node_modulesout of sync between worktrees -- You bumped a dependency in worktree A; worktree B still has the old version installed. Fix: Re-runnpm install(or your equivalent) per worktree after dependency changes. -
Merge commit goes to the wrong branch -- You ran
git merge featurefrom a worktree that haddevelopchecked out, notmain. Fix: Rungit branch --show-currentbefore merging. Usegit reset --hard ORIG_HEADto undo the merge if it hasn't been pushed.
Alternatives
Other ways to solve the same problem -- and when each is the better choice.
| Alternative | Use When | Don't Use When |
|---|---|---|
git stash + branch switch | Quick 30-second context switch | The interruption will last more than a few minutes |
| Two clones | You need fully isolated .git directories (e.g., destructive history rewrites) | You want shared history -- worktrees are strictly cheaper |
git rebase main (in feature worktree) | Personal branch, want clean linear history | Branch is shared -- prefer git merge main to avoid force-pushing |
git merge --no-ff feature | Want a permanent merge commit recording the integration | You prefer a flat history; use rebase + fast-forward instead |
git merge --squash feature | Many small commits should land as one logical change | You want to preserve the individual commits for git bisect |
FAQs
How do I create a worktree on a remote branch?
git fetch origin
git worktree add ../review origin/feature/teammate-branch- Git creates a detached HEAD by default. To track the remote branch as a local one, use
-b:git worktree add ../review -b feature/teammate-branch origin/feature/teammate-branch.
What's the difference between git switch and git checkout in a worktree?
- Both work.
git switchwas added in Git 2.23+ to clarify intent (branches only). git checkoutis overloaded -- it switches branches and restores files. A typo can clobber uncommitted changes.- Inside a worktree, prefer
git switch <branch>for branch operations andgit restore <file>for file ones.
Can I git pull in one worktree and have it affect the others?
git pullonly fast-forwards or merges the branch checked out in the worktree where you ran it.- The fetched remote refs (
origin/main, etc.) become visible in all worktrees, but the local branch pointers in other worktrees don't move automatically.
How do I rebase a feature worktree onto the latest main?
cd ../my-feature
git fetch origin
git rebase origin/maingit fetchupdates the remote ref.git rebase origin/mainreplays your feature commits on top.- If you have local commits to push afterward, you'll need
git push --force-with-lease(never plain--force).
What happens if I git merge feature-branch from the wrong worktree?
- The merge commit lands on whatever branch the current worktree has checked out, which may not be what you wanted.
git branch --show-currentbefore merging avoids this.- If you haven't pushed,
git reset --hard ORIG_HEADundoes the merge cleanly.
Can I cherry-pick a commit from another worktree's branch?
git cherry-pick <sha>- Yes. The commit lives in the shared
.gitfolder, so cherry-pick works across worktrees with no special syntax. - If the SHA is on a branch you've never fetched, run
git fetchfirst.
How do I compare two branches checked out in different worktrees?
git diff main..feature-branch
git log main..feature-branch --oneline- These work from any worktree. You don't need to switch into either branch.
- For a side-by-side file comparison, use
git difftool main..feature-branch.
I removed a worktree folder with rm -rf -- now git worktree list shows it. How do I clean up?
git worktree prune- This removes metadata for any worktree whose folder is missing.
- Add
--verboseto see what got pruned.
How do I move a worktree to a different location?
git worktree move ../old-path ../new-path- Use
git worktree move, notmv. Git updates internal links to track the new location. - If you already moved the folder with
mv, rungit worktree repair ../new-pathfrom inside the main worktree.
Should I run my dev server from a feature worktree or the main one?
- Either works. Common pattern: keep one worktree as your "running" copy and use other worktrees for review or hotfixes.
- Each worktree has its own
node_modules, so dependency changes don't cross over -- a feature is isolated.
Related
- Git Worktrees Intro -- The mental model and basic commands
- Merging & Rebasing -- Combining branches across worktrees
- Merge Conflict Resolution Checklist -- When a cross-worktree merge conflicts
- Essential Git Commands -- The day-to-day commands every worktree workflow builds on