How to Remove a Git Worktree (The Right Way)
TL;DR
git worktree remove <path> # clean removal
git worktree remove --force <path> # with uncommitted changes
git worktree prune # clean up stale references
These three commands cover 99% of worktree removal. The rest of this article explains when to use each, what can go wrong, and how to recover.
Why Not Just rm -rf?
The #1 worktree mistake is treating it like a normal folder:
rm -rf ../myapp-old-feature # ❌ DON'T DO THIS
This deletes the files but leaves metadata inside the main repo pointing at the now-missing worktree:
.git/worktrees/myapp-old-feature/
Now Git thinks the worktree still exists. You'll see:
git worktree listshows a ghost entrygit branch -d feat/old-featurefails with "Cannot delete branch checked out at ..."- Some Git operations may produce odd warnings
Correct flow: use git worktree remove — it handles both the files and the metadata.
The Clean Path: git worktree remove
git worktree remove ../myapp-old-feature
This succeeds when:
- ✅ The worktree has no uncommitted changes
- ✅ The worktree has no untracked files (or they're all gitignored)
- ✅ The worktree isn't locked
Git deletes the folder and the metadata in one atomic step. No stale state.
After removal, the branch itself still exists:
git branch -d feat/old-feature # merged branches
git branch -D feat/old-feature # force (unmerged)
For the specific "Cannot delete branch" error during
branch -d, see Fix: Cannot Delete Branch Used by Worktree.
When Clean Remove Refuses: --force
If the worktree has uncommitted changes:
$ git worktree remove ../myapp-old-feature
fatal: '../myapp-old-feature' contains modified or untracked files, use --force to delete it
Your options:
Option A: Save your work first (recommended)
cd ../myapp-old-feature
git status # what's uncommitted?
git stash # stash it
# or
git add . && git commit -m "WIP"
# or
git push origin HEAD # back it up remotely
cd -
git worktree remove ../myapp-old-feature
Option B: Force it (if you know changes are disposable)
git worktree remove --force ../myapp-old-feature
--force deletes the folder along with any uncommitted work. There is no recovery — the changes are gone.
Cleaning Up Stale Worktrees: prune
git worktree prune scans .git/worktrees/ and removes metadata for worktrees whose folders no longer exist:
git worktree prune
Use this when:
- You (or a teammate) accidentally
rm -rf'd a worktree folder - You moved the worktree to external media that's now disconnected
- A crash left orphaned metadata
Add -v to see what's being pruned:
git worktree prune -v
# Removing worktrees/myapp-crashed: gitdir file points to non-existent location
For a preview without actually pruning:
git worktree prune --dry-run --verbose
Locked Worktrees Need Unlocking First
Worktrees can be locked to protect them from accidental pruning (e.g., a worktree on a USB drive that isn't always connected):
$ git worktree remove ../myapp-on-usb
error: cannot remove a locked working tree, lock reason: USB drive
Unlock, then remove:
git worktree unlock ../myapp-on-usb
git worktree remove ../myapp-on-usb
Or force past the lock (risky if the folder is legitimately unavailable):
git worktree remove --force ../myapp-on-usb
Real-World Scenarios
Scenario 1: Finished a feature, merging cleanly
cd ~/projects/myapp-feat-auth
git push origin feat/auth
# create PR, get it merged
cd ~/projects/myapp
git fetch origin && git pull
git worktree remove ../myapp-feat-auth
git branch -d feat/auth
Scenario 2: Abandoned experiment
cd ~/projects/myapp
git worktree remove --force ../myapp-crazy-idea
git branch -D experiment/crazy-idea
Scenario 3: Recovering from rm -rf
git worktree list # shows ghost entry
git worktree prune -v # cleans metadata
git branch -D feat/lost # now you can delete the branch
Scenario 4: Worktree on unplugged external drive
git worktree list
# /Volumes/USB/myapp-backup (unavailable: lock reason: USB offline)
git worktree unlock /Volumes/USB/myapp-backup
git worktree remove --force /Volumes/USB/myapp-backup
# or, if you just want to forget it exists:
git worktree prune
Removing Worktrees in Bulk
For cleanup day, when you have 10 worktrees to kill:
Script: Remove all worktrees except the main one
git worktree list --porcelain | awk '
/^worktree / { wt=$2 }
/^bare/ { next }
/^$/ { if (wt && wt != main) print wt; wt="" }
NR==1 { main=$2 }
END { if (wt && wt != main) print wt }
' | xargs -I{} git worktree remove --force {}
⚠️ This deletes uncommitted changes in every worktree except
main. Dry-run first:
git worktree list --porcelain | awk '/^worktree / && $2 != "'"$(pwd)"'" { print $2 }'
Interactive: pick-and-delete with fzf
git worktree list | fzf -m | awk '{print $1}' | xargs -I{} git worktree remove {}
-m allows multi-select with tab. Much safer than bulk-kill.
What git worktree remove Does NOT Do
- ❌ Does not delete the branch (that's
git branch -d) - ❌ Does not push your branch to origin (commit/push first!)
- ❌ Does not recover after
--force— gone is gone - ❌ Does not prune OTHER stale worktrees (that's
prune)
Be explicit about each step in cleanup scripts.
Why Bulk Cleanup Gets Annoying
If you're using worktrees heavily — say, one per AI coding task — you'll accumulate them fast. After a week:
myapp # main
myapp-feat-auth # merged 3 days ago
myapp-feat-search # abandoned
myapp-bug-203 # merged 2 days ago
myapp-explore-postgres # maybe use later?
myapp-refactor-api # WIP
myapp-docs-update # merged yesterday
Terminal cleanup rituals get old fast. This is what ParallelCode solves: all your worktrees in one dashboard, with status, last-activity, merge state, and a one-click "archive" or "delete" for each.
Download ParallelCode → — free, and worth the 30 seconds of install to never
git worktree pruneby hand again.
Summary: Removal Checklist
Before running git worktree remove:
- Have you committed or pushed your work? (
git statusin the worktree) - Do you also want to delete the branch? (
git branch -dafter) - Is the worktree locked? (
git worktree unlock) - Is the folder still there? (if not →
git worktree prune)
Commands:
git worktree remove <path> # 99% of the time
git worktree remove --force <path> # accept data loss
git worktree prune # if folder is already gone
git worktree unlock <path> # if locked
git branch -d <branch> # after removal, delete branch
Related Reading
Related posts
Claude Code + Git Worktree - Run Multiple AI Agents in Parallel
The complete guide to using Claude Code with git worktree. Run 3+ Claude Code instances simultaneously, each on its own branch, without merge conflicts or context pollution.
Read moreFix "Cannot Delete Branch Used by Worktree" in Git
You hit "error, Cannot delete branch 'X' checked out at '...'" when running git branch -d. Here's exactly why Git blocks you, and the 3 ways to fix it.
Read moregit worktree add: Complete Command Reference
Every flag, every argument, every variation of git worktree add - explained with runnable examples. Creating branches, detached worktrees, tracking remote branches, and more.
Read more