git worktree remove: delete a worktree and fix every error
The exact command, then every error you can hit, with the message as git prints it. All of it was run on git 2.50.1.
To remove a git worktree, run git worktree remove with its path, from any checkout
of the repository:
git worktree remove ../repo-feature-a
That deletes the worktree folder and git's record of it. It does not delete the branch. It
refuses if the worktree has uncommitted changes (add --force) or is locked
(unlock it first). There is no git worktree delete: remove
is the command. Every error below is pasted from a real run.
contains modified or untracked files: commit or stash, or add--forceto throw the changes away.cannot delete branch ... used by worktree: remove the worktree first, thengit branch -d.cannot remove a locked working tree:git worktree unlock <path>, orremove -f -f.- Folder deleted by hand:
git worktree prune. - Folder moved by hand:
git worktree repair <new-path>.
Remove a worktree
Pass the path exactly as git worktree list shows it. Absolute and relative paths
both work.
git worktree list
git worktree remove ../repo-feature-a
A clean remove prints nothing. Run git worktree list again to confirm. Four things worth knowing:
- The branch stays. Delete it separately, see below.
- Ignored files go with the folder. Anything in
.gitignore(node_modules,.env, build output) is deleted without--force, and git cannot bring it back. - You can remove the worktree you are standing in (
git worktree remove .), but your shell is then in a deleted directory.cdout first. - Git does not check for a rebase in progress. A worktree stopped mid-rebase with a clean tree is removed without a warning. Run
git rebase --abortor finish it first.
fatal: '../repo-feature-a' contains modified or untracked files, use --force to delete it
The worktree has a changed tracked file or an untracked file that is not ignored, so
git worktree remove will not delete it. See what it would lose:
git -C ../repo-feature-a status --short
To keep the work, commit it, or stash it. Stashes belong to the repository, not the worktree, so a stash survives the removal:
git -C ../repo-feature-a stash -u
git worktree remove ../repo-feature-a
To throw the work away, force it. This deletes the uncommitted changes for good, with no undo:
git worktree remove --force ../repo-feature-a
--force does not override a lock (see locked worktrees) and
it is not needed for ignored files.
error: cannot delete branch 'feature-a' used by worktree at '/Users/you/code/repo-feature-a'
Git will not delete a branch that a worktree has checked out. Both git branch -d
and git branch -D fail with this message. Remove the worktree first, then the
branch:
git worktree remove ../repo-feature-a
git branch -d feature-a
If the branch has commits that are not merged, -d stops again:
error: the branch 'feature-a' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature-a'
Use git branch -D feature-a only when you are sure you do not need those commits.
Two variations of the same error:
- You already deleted the folder by hand. The error stays until git forgets the worktree: run
git worktree prune, then delete the branch. - The branch is checked out in your main checkout (the message names the main repo's path). Switch the main checkout to another branch with
git switch, then delete it.
The mirror image, checking a branch out in a second worktree, is covered in the git worktree cheat sheet.
fatal: cannot remove a locked working tree
The full message has two lines. With no lock reason:
fatal: cannot remove a locked working tree;
use 'remove -f -f' to override or unlock first
With a reason, the first line carries it:
fatal: cannot remove a locked working tree, lock reason: on usb drive
use 'remove -f -f' to override or unlock first
Someone, or some tool, ran git worktree lock on it. git worktree list
shows locked next to it, and git worktree list -v shows the reason.
Unlock it, then remove it:
git worktree unlock ../repo-feature-a
git worktree remove ../repo-feature-a
Or do both in one step by passing force twice. A single --force is still refused:
git worktree remove -f -f ../repo-feature-a
Worktree folder deleted by hand: prunable
If you deleted the folder with rm -rf or Finder instead of
git worktree remove, git still has a record of it. git worktree list
marks it:
/Users/you/code/repo 097e9f9 [main]
/Users/you/code/repo-feature-a 097e9f9 [feature-a] prunable
Clear every stale record with prune. Add -n -v first to preview:
git worktree prune -n -v
git worktree prune
The preview prints one line per record, such as
Removing worktrees/repo-feature-a: gitdir file points to non-existent location.
git worktree remove ../repo-feature-a also works on a missing folder. Neither deletes
the branch.
If you try to create the worktree again before pruning, git stops you:
fatal: '../repo-feature-a' is a missing but already registered worktree;
use 'add -f' to override, or 'prune' or 'remove' to clear
Run git worktree prune and repeat the add.
fatal: '../repo-feature-a' is a missing but locked worktree
The folder is gone and the worktree was locked, for example one on a drive that is not mounted. The full message:
fatal: '../repo-feature-a' is a missing but locked worktree;
use 'add -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear
git worktree prune skips a locked worktree without saying anything, which is why it
seems to do nothing. Unlock first, then prune:
git worktree unlock ../repo-feature-a
git worktree prune
Or remove it in one step with git worktree remove -f -f ../repo-feature-a. If the
drive is only unplugged, plug it back in instead: a lock exists to protect exactly that case.
fatal: '../repo' is a main working tree
You pointed git worktree remove at the original checkout, the one that holds the
.git directory. Only linked worktrees can be removed. Check which one is which with
git worktree list: the main worktree is always the first line. To get rid of the
whole repository, remove the linked worktrees first, then delete the folder yourself.
fatal: '../repo-feature-b' is not a working tree
The path does not match any worktree, usually a typo or a path relative to the wrong
directory. A plain folder that is not a worktree gives the same message. Copy the path from
git worktree list.
fatal: working trees containing submodules cannot be moved or removed
Git refuses to remove a worktree that has an initialized submodule, even when nothing is uncommitted. Check the submodule for unpushed work, then force it:
git worktree remove --force ../repo-feature-a
Worktree folder moved by hand: git worktree repair
Moving a worktree folder with mv breaks the link between it and the main repository.
Git then lists it as prunable at the old path, and pruning would forget it. Do not
prune. Run repair from the main repository and pass the new path:
git worktree repair ../repo-feature-a-renamed
repair: gitdir incorrect: /Users/you/code/repo/.git/worktrees/repo-feature-a/gitdir
The repair: line confirms what was fixed. Without a path, git worktree
repair found nothing to fix in this case, so pass the path. Next time use
git worktree move ../repo-feature-a ../repo-feature-a-renamed, which updates both
sides.
If you moved the main repository instead, every worktree breaks, and commands inside them print:
fatal: not a git repository: /old/path/repo/.git/worktrees/repo-feature-a
Run repair from the moved main repository and pass each worktree's path:
cd /new/path/repo
git worktree repair ../repo-feature-a
repair: .git file broken: /new/path/repo-feature-a
Remove many worktrees at once
This script, run from your main checkout, removes every worktree whose branch is already merged
into main and then deletes that branch. It never forces: worktrees with
uncommitted changes or a lock print their error and are skipped, and unmerged ones are not
touched. Paths with spaces are fine.
#!/usr/bin/env bash
# Remove every linked worktree whose branch is already merged into main.
base=main
git worktree prune
main_path=$(git worktree list --porcelain | awk '/^worktree /{print substr($0,10); exit}')
git worktree list --porcelain |
awk -v RS= -F'\n' '{
path = ""; branch = ""
for (i = 1; i <= NF; i++) {
if ($i ~ /^worktree /) path = substr($i, 10)
if ($i ~ /^branch refs\/heads\//) branch = substr($i, 19)
}
if (path != "" && branch != "") print path "\t" branch
}' |
while IFS=$'\t' read -r path branch; do
[ "$path" = "$main_path" ] && continue
if git merge-base --is-ancestor "$branch" "$base"; then
git worktree remove "$path" && git branch -d "$branch"
fi
done
One catch: a branch with no commits of its own counts as merged, so a worktree you created a
minute ago and have not touched is removed too. Read the list from
git worktree list before you run it. To clear only stale records, a plain
git worktree prune is enough.
Cleaning up after AI coding agents
Agent worktrees are ordinary git worktrees, so everything above applies, and they show up in
git worktree list even when the tool created them somewhere else.
- Claude Code removes a clean, unnamed interactive session's worktree on exit. Non-interactive
-pruns skip cleanup, so those pile up until you remove them (unlock first if one is locked). See Claude Code worktrees. - Codex keeps up to 15 managed worktrees and deletes older ones itself, after saving a snapshot. See Codex worktrees.
- Cursor cleans up on a schedule, and
/delete-worktreeremoves one on demand. See Cursor worktrees.
Clean up worktrees without the terminal
teebe is a free native macOS app that lists the worktrees of every repo you
add. From teebe 0.8 it can also tell you which ones are safe to delete and remove them, using
the same git worktree remove described above, never with --force.
- It sorts worktrees into three groups: Uncommitted changes, Not merged and Safe to delete. A worktree is safe to delete when its branch is merged into the repo's default branch,
main,master,dev,developor a comparison branch you choose (a squash merge counts), with nothing uncommitted. - A bin on the Safe to delete group removes them all. A confirmation lists every worktree, and an Also delete the branches checkbox, off by default, deletes the local branches too. Remote branches are never touched. A branch is deleted only if it is still at the commit teebe checked and still merged.
- It refuses what git would lose or what is in use: uncommitted changes, locked or detached worktrees, submodules, a rebase, merge or cherry-pick in progress, and any worktree where an agent is working or that is open in a terminal or editor.
- It warns before deleting ignored files. The confirmation says Also deletes 214 gitignored files. Git can’t restore these files and names the ones that look hard to replace, like
.env.local. - A worktree whose folder you deleted by hand is forgotten automatically, like
git worktree prunefor that one record, unless it is locked, on a drive that is not mounted, or still holds commits no branch has.
A clean worktree that is not merged yet can still be removed from its right-click menu, with
Remove Worktree…. Only the folder goes, and its branch is kept. teebe does not run git worktree repair or unlock anything for you. See
git worktree managers for macOS for how it
compares to the alternatives.
Frequently asked questions
Is there a git worktree delete command?
No. The command is git worktree remove <path>. It deletes the worktree folder and git's record of it, and leaves the branch alone. Typing git worktree delete prints error: unknown subcommand: `delete' and the list of real subcommands.
Does git worktree remove delete the branch?
No. The branch and its commits stay. Delete the branch afterwards with git branch -d <branch>, or git branch -D <branch> if it is not merged. Git refuses to delete a branch while a worktree still has it checked out, so remove the worktree first.
How do I remove a worktree that has uncommitted changes?
Either commit or stash the changes first, or run git worktree remove --force <path>, which deletes the folder and the uncommitted changes for good. Stashes are shared by all worktrees of a repository, so a stash made inside the worktree survives its removal.
What does git worktree prune do?
It deletes git's records of worktrees whose folder no longer exists, for example one you removed with rm -rf or Finder. It never touches a locked worktree or a branch. Run git worktree prune -n -v first to see what it would remove.
How do I remove a locked worktree?
Run git worktree unlock <path>, then git worktree remove <path>. To do it in one step, pass force twice: git worktree remove -f -f <path>. A single --force is not enough for a locked worktree.
How do I delete a worktree I already deleted by hand?
Run git worktree prune. Git still lists the worktree, marked prunable, until you do. git worktree remove <path> also works for a missing folder. Neither deletes the branch.
curl -fsSL https://teebe.io/install.sh | bash
Free · open source · macOS 14+. Back to teebe.io →