ExitWorktree's safety check false-positives after every squash-merge — ancestry is the wrong predicate

Status Closed — duplicate
Maintainer reply None cached
Activity 2 comments · opened Aug 7, 2026 · closed Aug 15, 2026

ExitWorktree refuses to remove a worktree whose branch has "commits not on the original branch" — an ancestry check. A squash-merge never makes branch commits ancestors of the default branch, so after every squash-merge the refusal fires on work that is fully landed:

Error: Worktree has 18 commits on <branch>. Removing will discard this work permanently.

The message is factually right and practically wrong: discarding loses nothing, because the squash commit carries the identical tree. The check asks "are these commits reachable from main?" — the question that matters is "would removing this lose any work?" Tree equality answers the real one: git diff --quiet origin/<default> (silent ⇒ nothing to lose).

The hazard is reflex-training: a check that fires on every routine merge teaches users to pass discard_changes: true reflexively, so the one time it fires for a real reason (a commit that never landed), it reads exactly like the previous twenty false alarms.

Suggestion: when the ancestry check fails, run the tree-equality check before refusing — if the worktree's tree is identical to the default branch's, allow removal (or downgrade to an informational note). Squash-merge is the default merge mode on many repos, so the false positive presumably fires for most worktree users.

(Our local workaround, for what it's worth: standing worktrees entered via EnterWorktree path:, which are never removed at all.)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗