-
Notifications
You must be signed in to change notification settings - Fork 2.3k
fix(bin): prune merged task branches across all project modes #2768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
trevorallred
wants to merge
10
commits into
kunchenguid:main
from
trevorallred:fm/firstmate-merged-branch-hardening
Closed
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
fcf2f51
fix(bin): drop safely-merged fm/<task-id> branches, add a backstop sweep
trevorallred d762fd4
no-mistakes(review): Prevent unsafe gone-upstream branch deletion
trevorallred 0c82024
no-mistakes(document): Document merged task branch cleanup
trevorallred 200844e
no-mistakes: apply CI fixes
trevorallred 418e88f
no-mistakes: apply CI fixes
trevorallred 0b6229f
no-mistakes: apply CI fixes
trevorallred 39c4249
no-mistakes: apply CI fixes
trevorallred 81aa22a
no-mistakes: apply CI fixes
trevorallred 2fcb5c0
no-mistakes: apply CI fixes
trevorallred a5a2396
fix(bin): make the merged-branch backstop sweep default-on again
trevorallred File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| #!/usr/bin/env bash | ||
| # Shared "is this branch provably safe to delete?" decision procedure. | ||
| # | ||
| # ONE owner for the merged-branch proof that fm-fleet-sync.sh's periodic | ||
| # fm/<task-id> sweep relies on (fm-teardown.sh's own inline branch-drop stays | ||
| # on its existing, stronger, GitHub-aware landedness proof - see that | ||
| # script's header - and is not re-derived here). A branch is provably safe to | ||
| # delete iff ALL of the following hold: | ||
| # 1. it exists as a local branch in the repo; | ||
| # 2. it is not currently checked out in ANY worktree of that repo, linked or | ||
| # main - deleting a checked-out branch would fail anyway, but checking | ||
| # first keeps this a pure decision procedure with no destructive side | ||
| # effect on the caller's own probing; | ||
| # 3. its tip is an ancestor of the given "merged into" ref (a clean | ||
| # fast-forward, or any non-squash merge, already contains it - git's own | ||
| # `branch -d` can verify this itself). | ||
| # Upstream "[gone]" is deliberately excluded: deletion of a remote ref does | ||
| # not prove that its work landed. The separately-owned prune_gone_branches | ||
| # flow covers squash-merged PR cleanup, while fm-teardown.sh uses its existing | ||
| # GitHub-aware landedness check for inline cleanup. | ||
| # ANY uncertainty - the branch does not exist, a worktree still has it out, or | ||
| # neither proof holds - returns non-zero (NOT safe): fail safe, never force a | ||
| # delete this cannot prove. The caller decides what "not safe" means (leave it | ||
| # alone and move on, never an error worth failing over). | ||
|
|
||
| # fm_branch_worktree_branches <repo>: newline list of branch shortnames | ||
| # currently checked out in any worktree of <repo> (the main checkout included). | ||
| fm_branch_worktree_branches() { | ||
| local repo=$1 | ||
| git -C "$repo" worktree list --porcelain 2>/dev/null | sed -n 's#^branch refs/heads/##p' | ||
| } | ||
|
|
||
| # fm_branch_is_safely_merged <repo> <branch> <merged_into_ref> [expected_tip]: | ||
| # the proof itself (see header). When <expected_tip> is supplied, it additionally | ||
| # proves that is still the branch's current tip, binding a caller's later | ||
| # expected-old-value deletion to precisely the tip this proof examined. Never | ||
| # inspects or changes anything but refs. Refuses a | ||
| # <branch> that IS the "merged into" ref itself as a defensive guard against a | ||
| # caller accidentally naming the protected/default branch - every branch is | ||
| # trivially its own ancestor, so without this guard that self-comparison would | ||
| # otherwise look "safely merged". | ||
| fm_branch_is_safely_merged() { | ||
| local repo=$1 branch=$2 merged_into=$3 expected_tip=${4:-} tip | ||
| [ -n "$branch" ] || return 1 | ||
| [ "refs/heads/$branch" != "$merged_into" ] || return 1 | ||
| tip=$(git -C "$repo" rev-parse --verify --quiet "refs/heads/$branch") || return 1 | ||
| [ -z "$expected_tip" ] || [ "$tip" = "$expected_tip" ] || return 1 | ||
| fm_branch_worktree_branches "$repo" | grep -Fxq -- "$branch" && return 1 | ||
| if [ -n "$merged_into" ] \ | ||
| && git -C "$repo" merge-base --is-ancestor "$tip" "$merged_into" 2>/dev/null; then | ||
| return 0 | ||
| fi | ||
| return 1 | ||
| } | ||
|
|
||
| # fm_branch_delete_if_safely_merged <repo> <branch> <merged_into_ref>: delete | ||
| # <branch> in <repo> only when fm_branch_is_safely_merged proves it, printing | ||
| # nothing itself (callers report their own outcome). `git branch -d` always | ||
| # judges mergedness against its checkout's HEAD, rather than an explicit ref. | ||
| # Use a short-lived detached worktree at <merged_into> so its final safe delete | ||
| # repeats the SAME proof as the caller, while still letting Git refuse deletion | ||
| # if another worktree checked out the branch after our proof. Returns non-zero, | ||
| # unchanged, for anything the proof does not cover. | ||
| fm_branch_delete_if_safely_merged() { | ||
| local repo=$1 branch=$2 merged_into=$3 git_dir prune_worktree delete_status | ||
| fm_branch_is_safely_merged "$repo" "$branch" "$merged_into" || return 1 | ||
| git_dir=$(git -C "$repo" rev-parse --absolute-git-dir 2>/dev/null) || return 1 | ||
| prune_worktree=$(mktemp -d "$git_dir/fm-branch-prune.XXXXXX") || return 1 | ||
| rmdir "$prune_worktree" || return 1 | ||
| git -C "$repo" worktree add --detach -q "$prune_worktree" "$merged_into" || return 1 | ||
| git -C "$prune_worktree" branch -d -- "$branch" >/dev/null 2>&1 | ||
| delete_status=$? | ||
| git -C "$repo" worktree remove "$prune_worktree" >/dev/null 2>&1 || true | ||
| return "$delete_status" | ||
| } |
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
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
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.