fix: treat patch-equivalence to default as a merged cleanup signal#883
Merged
Conversation
Squash merges create a new commit on the default branch, so the original branch tip is never an ancestor of origin/main. The cleanup classifier already computed patch-equivalence via git cherry but treated it as a skip reason. - detect_local_merged_signal() falls back to git cherry patch-equivalence and emits patch-equivalent-merged, preserving the local branch. - WorktreeCleanupCandidateClassifier passes preserve_local_branch through so removal skips local branch deletion. - active-no-signal merged_apply accepts patch_equivalent_default rows, with open-PR/dirty/unpushed guards evaluated first. - Tests verify squash-equivalent branches are removable and guards still block dirty/open-PR rows. Closes #882
Contributor
Homeboy Results —
|
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.
Root cause
workspace worktree cleanup/active-no-signal-merged-applydecided a branch was "merged to default" primarily via git ancestry (rev-list --count origin/main..branch). Squash merges create a brand-new commit onorigin/main, so the original branch tip is never an ancestor oforigin/main. Every squash-merged worktree was therefore classifiednot_merged_to_defaultand never auto-cleaned.The tooling already computed patch-equivalence (
git cherry) and emitted the labelpatch_equivalent_default, but then treated it as a skip reason instead of a removal signal.What changed
WorkspaceWorktreeCleanupEngine::detect_local_merged_signal()After the ancestry check fails, the method now falls back to
git cherry <default_ref> <branch_ref>. If every local commit has a patch-equivalent match on the remote default branch, it returns a new signalpatch-equivalent-mergedand markspreserve_local_branch: true(the commits are equivalent but not contained, so we keep the local branch rather than force-delete it).WorktreeCleanupCandidateClassifier::classify_merge_signal_path()Passes
preserve_local_branchfrom the signal into the candidate row so the removal loop skips local-branch deletion for squash-merged worktrees.WorkspaceActiveNoSignalCleanupsuggest_active_no_signal_action()now evaluates dirty/unpushed and open-PR guards before patch-equivalence, so an open PR or dirty worktree cannot be classifiedpatch_equivalent_default.worktree_active_no_signal_merged_apply()acceptspatch_equivalent_defaultrows and dispatches to a new metadata builder that revalidates current state viagit cherry.build_current_patch_equivalent_to_default_cleanup_evidence()validates clean/unpushed and re-proves patch-equivalence before writingSTATE_MERGEDcleanup metadata.Safety guards kept intact
unsafe_dirty_or_unpushed/dirty_worktree.unpushed_commits.active_open_pr.patch-equivalent-mergedsignal only fires after the existing dirty/unpushed probes have passed.GitHub PR state
Not wired into the default cleanup path. The fix is intentionally pure-git (
git cherry) and does not require a GitHub API call, matching the issue's request to prefer the self-contained fix as primary.Verification
homeboy review data-machine-code lint --changed-since main→ passed (0 PHPCS/PHPStan findings).homeboy review data-machine-code test --changed-since main→ test runner could not start because the local WP Codebox CLI is not configured (wp-codebox --versionfailed). This is an environment bootstrap issue, not a code issue.php tests/*.phpall pass, including the extendedtests/worktree-cleanup-patch-equivalence.phpwhich now asserts:patch-equivalent-mergedsignal,patch_equivalent_default,active_open_pr,unsafe_dirty_or_unpushed,active_no_signal_merged_applyplanspatch_equivalent_defaultrows.Closes #882