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.
# Create + checkout an existing branch in a new worktreegit worktree add ../feature-branch feature-branch# Create a new branch and check it out in a new worktreegit worktree add ../new-feature -b new-feature# Detached HEAD on a specific commit or taggit worktree add ../hotfix abc1234# List worktrees and the branch each one has checked outgit worktree list# Remove a worktree once you're donegit worktree remove ../feature-branch# Clean up stale entries after a folder was deleted manuallygit worktree prune
When to reach for this: Any worktree-driven workflow -- feature dev, hotfix isolation, PR review, side-by-side comparison.
# 1. Start the feature in a new worktree on a new branchgit worktree add ../my-feature -b my-feature# 2. Move into it and work normallycd ../my-feature# ...edit files, run tests, commit...git add .git commit -m "feat: scaffold my-feature"# 3. Walk back to main and mergecd ../main-repogit switch maingit pull origin maingit merge my-feature# 4. Push and clean upgit push origin maingit worktree remove ../my-featuregit branch -d my-feature
What 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.
# Create a new worktree and checkout an existing branchgit worktree add ../feature-branch feature-branch# Create a new branch AND check it out in a new worktreegit 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 worktreegit switch -c <new-branch> # Create + switch
Tip: 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.
git branch -a # All branches (local + remote)git branch -v # With last commit infogit worktree list # Which branch each worktree has checked outgit worktree list --porcelain # Machine-readable for scripts
git worktree list is the answer to "wait, where did I leave that hotfix?"
Merging happens in the target worktree -- usually the one with main or a release branch checked out.
# From your main worktree:cd ../main-projectgit switch main # or: git checkout maingit 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 optionsgit merge --no-ff feature-branch # Always create a merge commitgit merge --squash feature-branch # Squash changes (then commit manually)# Rebase instead, for a cleaner historygit switch feature-branch # Switch into the feature branch's worktree firstgit rebase maingit switch maingit merge feature-branch # Now a clean fast-forward
Cross-worktree merge example:
Finish work and commit inside ../feature-worktree.
cd back 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.
git fetch origin # Updates remote refs -- visible from all worktreesgit pull origin main # Fetch + merge into the worktree you ran this in# Update a feature worktree's basecd ../my-featuregit fetch origingit rebase origin/main # Replay your feature commits on top of latest main
Key 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.
# 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-repogit fetch origingit worktree add ../hotfix -b hotfix/login-500 origin/maincd ../hotfix# ...debug, fix, commit, push, open PR...git push -u origin hotfix/login-500# Once the PR is merged, clean upcd ~/projects/main-repogit worktree remove ../hotfixgit branch -D hotfix/login-500 # If the remote branch was deleted on merge# Walk back to your feature work, exactly as you left itcd ../my-feature
# A teammate pushed a branch you need to reviewgit fetch origingit worktree add ../review-pr-482 origin/feature/teammate-thingcd ../review-pr-482npm installnpm run dev# ...read code, test it, leave PR comments...# Tear it down when donecd ../main-repogit worktree remove ../review-pr-482
# Run two implementations at once for a real comparisongit worktree add ../approach-a -b experiment/approach-agit 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-bgit branch -D experiment/approach-b
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 feature onto origin/main inside ../my-feature, but in your main worktree you forgot to git pull first. Fix: Always git fetch + git pull in 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: Use git worktree add to create a new worktree; git switch/git checkout only changes the current one.
Stashes apply across worktrees and surprise you -- You stashed in worktree A, then git stash pop in worktree B applies the wrong files. Fix: Stashes are shared. Name them (git stash push -m "feature X wip") and review with git stash list before 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 a git pull triggers a confusing fast-forward refusal. Fix: Coordinate force-pushes; rerun git fetch + git reset --hard origin/feature in the other worktree if you're certain.
node_modules out of sync between worktrees -- You bumped a dependency in worktree A; worktree B still has the old version installed. Fix: Re-run npm install (or your equivalent) per worktree after dependency changes.
Merge commit goes to the wrong branch -- You ran git merge feature from a worktree that had develop checked out, not main. Fix: Run git branch --show-current before merging. Use git reset --hard ORIG_HEAD to undo the merge if it hasn't been pushed.
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 switch was added in Git 2.23+ to clarify intent (branches only).
git checkout is overloaded -- it switches branches and restores files. A typo can clobber uncommitted changes.
Inside a worktree, prefer git switch <branch> for branch operations and git restore <file> for file ones.
Can I `git pull` in one worktree and have it affect the others?
git pull only 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-featuregit fetch origingit rebase origin/main
git fetch updates the remote ref. git rebase origin/main replays 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-current before merging avoids this.
If you haven't pushed, git reset --hard ORIG_HEAD undoes 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 .git folder, so cherry-pick works across worktrees with no special syntax.
If the SHA is on a branch you've never fetched, run git fetch first.
How do I compare two branches checked out in different worktrees?