git worktree remove <path> deletes the working directory and its administrative record together. It refuses when the worktree has modified or untracked files, and refuses twice as hard when the worktree is locked. It never deletes the branch. If you already deleted the directory by hand, remove still works on the path, and git worktree prune clears every stale record at once.
git worktree remove <path>is the correct way. Pass the path, never the branch name.- It refuses when dirty, and untracked files count. That refusal is protecting you.
- A locked worktree needs
--forcetwice, orunlockfirst. - Removing a worktree does not delete the branch or its commits.
- Already deleted the directory?
removestill works, andpruneclears all of them. - Check the diff before you force. Uncommitted agent work is still work.
Removing one
Find it, look at it, remove it. The middle step is the one people skip and the one that saves them.
# what exists
$ git worktree list
/Users/you/code/app ad7da80 [main]
/Users/you/code/app-auth ad7da80 [feature/auth]
# look before you delete
$ git -C ../app-auth status --short
M src/auth.ts
?? src/auth.test.ts
# remove it
$ git worktree remove ../app-auth
fatal: '../app-auth' contains modified or untracked files, use --force to delete it
# then, if you are sure
$ git worktree remove --force ../app-auth
Every refusal, and what it means
Verbatim messages from git 2.54.
| Message | Means | Do this |
|---|---|---|
contains modified or untracked files | The tree is dirty | git -C <path> status, then --force |
cannot remove a locked working tree | Someone locked it deliberately | git worktree unlock <path>, or --force --force |
<path> is a main working tree | You aimed at the original clone | You cannot remove it; delete the whole directory |
<path> is not a working tree | Wrong path, or you passed a branch name | Copy the path from git worktree list |
working trees containing submodules cannot be moved or removed | Populated submodules inside | Deinit the submodules, or delete by hand and prune |
$ git worktree lock ../app-usb --reason "on an external disk"
$ git worktree remove ../app-usb
fatal: cannot remove a locked working tree, lock reason: on an external disk
use 'remove -f -f' to override or unlock first
# the polite route
$ git worktree unlock ../app-usb
$ git worktree remove ../app-usb
The branch is not removed
Removing a worktree removes a working directory. The branch, and every commit on it, stays exactly where it was. This surprises people who expect remove to be an undo.
# worktree gone, branch still there
$ git worktree remove ../app-auth
$ git branch --list "feature/*"
feature/auth
# delete the branch too, if it is merged
$ git branch -d feature/auth
# force delete an unmerged branch: this DOES orphan commits
$ git branch -D feature/auth
Removing every merged worktree at once
Once you routinely run several agents, cleanup becomes the chore. Drive it off the merge state rather than off memory.
#!/usr/bin/env bash
# Remove worktrees whose branch is already merged into main.
set -euo pipefail
git worktree list --porcelain \
| awk '/^worktree /{p=$2} /^branch /{print p, $2}' \
| while read -r path ref; do
branch="${ref#refs/heads/}"
[ "$branch" = "main" ] && continue
if git merge-base --is-ancestor "$branch" main 2>/dev/null; then
echo "merged, removing: $branch"
git worktree remove "$path" && git branch -d "$branch"
fi
done
If you forced it and want it back
Split this into two cases before you panic, because they have very different answers. Committed work is almost always recoverable. Uncommitted work is not. That asymmetry is the entire reason remove refuses on a dirty tree.
Read what git already told you
git branch -D prints the tip commit it just dropped. If the terminal is still open, the hard part is done.
$ git branch -D feature/auth
Deleted branch feature/auth (was 8ff611a).
Otherwise, find the dangling commit
Deleting a branch deletes its reflog too, so the commit becomes unreachable rather than gone. fsck lists exactly those.
$ git fsck --lost-found
dangling commit 8ff611a497ab01f62ecde2f78b0bea4f4ea88459
$ git log --oneline 8ff611a | head -3
8ff611a agent commit
45fc22d init
Give it a name again
$ git branch recovered 8ff611a
$ git worktree add ../app-recovered recovered
When you deleted the directory by hand
This is the common case, because rm -rf is the obvious thing to do. It leaves git holding a registration that points at nothing, and git worktree list starts annotating it as prunable.
$ rm -rf ../app-auth # the tempting shortcut
$ git worktree list
/Users/you/code/app ad7da80 [main]
/Users/you/code/app-auth ad7da80 [feature/auth] prunable
# option A: remove still works on the path
$ git worktree remove ../app-auth
# option B: clear every stale record at once
$ git worktree prune --dry-run --verbose
Removing worktrees/app-auth: gitdir file points to non-existent location
$ git worktree prune
The repair commands, and which situation each is for.
| Situation | Command |
|---|---|
| I want this worktree gone | git worktree remove <path> |
| I already deleted several directories | git worktree prune |
I moved a worktree with mv | git worktree repair <new-path> |
| I moved the whole repository | git worktree repair in the main worktree |
| I want to relocate one properly | git worktree move <from> <to> |
| A worktree lives on a disk that comes and goes | git worktree lock |
Questions people ask
Run git worktree remove <path> from inside the repository. It deletes the directory and clears the administrative record together. Pass the path shown by git worktree list, not the branch name.
It has modified or untracked files. Run git -C <path> status --short to see exactly what, then use --force only once you are sure you do not want them. Untracked files count, so a stray log file is enough to trigger the refusal.
Either git worktree unlock <path> then remove it normally, or pass --force twice: git worktree remove -f -f <path>. Git tells you this in the second line of the error message.
No. The branch and all its commits remain. Delete it separately with git branch -d, or -D to force an unmerged branch, which orphans the commits until the reflog expires.
Either git worktree remove <path>, which still works on a missing directory, or git worktree prune to clear every stale record at once. Use prune --dry-run --verbose first if you want to see the list.
No. git worktree remove refuses with "is a main working tree". The main worktree is the original clone, so removing it means deleting the repository. Delete the directory yourself if that is really what you want.
Parse git worktree list --porcelain, check each branch with git merge-base --is-ancestor against main, and remove the ones already merged. Use plain remove and branch -d so anything with unfinished work refuses instead of disappearing.
If it was committed, yes. git branch -D prints the tip commit it dropped, and git fsck --lost-found lists dangling commits after the fact. Recreate a branch at that sha. Unreachable objects survive until git gc prunes them, which defaults to two weeks. Uncommitted changes were never objects and cannot be recovered.
Sources
Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.