Never offer the default branch as a reclaimable worktree - #225
Merged
Conversation
main checked out in a linked worktree reads as landed against itself, clean, pushed and unbound — every signal the safe tier asks for — so the sweeper offered it as reclaimable, and removal would have deleted the trunk with `branch -D main`. The default branch now classifies as look before removing (or in use when a loop is running in it), is never selectable, and its row says so instead of "merged into main".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
With
mainchecked out in a linked worktree (here:graphcode-release-b3) while the primary checkout sits on a fix branch, worktree hygiene classified themainworktree as safe to remove:git cherryofmainagainst a base of[refs/heads/main, origin/main]is trivially empty (landed), the tree was clean, pushed, and unbound. It was counted as reclaimable and preselected — and the removal path always runsbranch -D, so accepting the offer would have deleted the trunk branch.Fix
All in the pure classifier (
WorktreeAssessment), so local and remote repos share it:isDefaultBranch(ref.branch == facts.defaultBranch)..lookBeforeRemoving) → prunable → locked → safe: the trunk can never land insafeToRemove, even as a prunable admin file.isRemovableis false for the default branch — no checkbox, since removal deletes the branch too.the default branch · never offered for removalinstead of the nonsensemerged into main.Every removal route is covered: sweeper preselection, the reclaimable counts on chips and menus, the resolve-moment auto-remove/ask, and card reclaim offers all gate on this tier.
Tests
WorktreeHygieneTests: +3 (default branch never a candidate, not safe when prunable, running loop still reads in use) — 21/21.WorktreeSweepFeatureTests+WorktreeRemovalTests: 31/31 across the three suites.