ExitWorktree's safety check false-positives after every squash-merge — ancestry is the wrong predicate
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.)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗