Fix the assumed main base in git bclean and bdone - #84
Open
mattmenefee wants to merge 1 commit into
Open
Conversation
`git bclean` still compared every branch against a hardcoded `main` and
read `git cherry`'s empty output as "already merged" — the defect fixed
in `cleanup` but left in place here. Run bare in a master-based
repository it force-deleted every local branch, unmerged work included.
`git bclean typo` and `git bclean ""` failed the same way, the latter
because `${1-main}` substitutes only when the argument is unset, not
when it is empty. `bdone` escaped the fault only because its
`git checkout main` failed first and short-circuited the chain.
Base resolution now lives in a single `git base` alias that reads
origin/HEAD and falls back to whichever of main or master exists locally
or on origin. `cleanup` takes an optional base and consults `git base`
when given none, `bclean` is a thin wrapper around it, and `bdone`
resolves the branch it checks out the same way, so the dangerous part
has one implementation rather than three.
Two further ways to lose work are closed in the same pass. `git cherry`
is handed fully qualified refs, since a tag sharing the base branch's
name shadows the branch and makes unmerged work compare clean under a
bare `main`. Branches carrying merge commits are skipped, because
`git cherry` ignores merges and a conflict resolution living only inside
one would read as merged. The repository's own base branch joins the
current branch as never deletable, so cleaning up against a longer-lived
base no longer eats a main that it contains.
Fixes #83.
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.
Fixes #83.
git cleanupwas fixed in #82, butbcleanstill carried the identical bug andbdoneavoided it only by accident. Run bare in a master-based repository,git bcleanforce-deleted every local branch — the same incident #82 describes, one alias over.Summary
git basealias that resolves the repository's base branch from origin/HEAD, falling back to whichever of main or master exists locally or on origin, and fails loudly when none doescleanupan optional base argument and have it consultgit basewhen given none;bcleanbecomes a thin wrapper aroundcleanupandbdoneresolves its checkout target the same way, so the dangerous comparison has one implementation rather than threegit cherry— a tag sharing the base branch's name shadowed the branch and made unmerged work compare clean under a baremain, which the exit-code guard could not catch because the command succeedsgit cherryignores merges and a conflict resolution living only inside one would read as merged and be deletedgit cleanup developpreviously ate amainthat develop containedgit for-each-ref refs/heads/, dropping the(HEAD detached at …)pseudo-entry that produced a confusing skip messagegit bclean ""is fixed as a side effect of the rewrite:${1-main}substituted only when the argument was unset, so an explicit empty string became a base named"".Test plan
Verified with a harness that extracts only the
[alias]section into a throwawayGIT_CONFIG_GLOBAL(withGIT_CONFIG_SYSTEM=/dev/nulland a scratchHOME) and exercises each scenario against real bare-origin clones. 23 assertions, all passing.git bcleanin a master-based repository resolves master and keeps unmerged branches (the filed bug)git bclean ""falls through to resolution instead of treating the empty string as a basegit bclean typo-brnchaborts with exit 1 and deletes nothingmainno longer masks unmerged work, and no longer produces a spurious base-branch errorgit bdoneresolves master in a master-based repository and checks it outgit bdone develophonors the explicit base and leavesmainintactrefs/heads/-Dbranch reaches nogit branch -Dunquoted — no option injectiongit baseprints the base on stdout and fails silently there when none resolvesdash -nandsh -n;shellcheck -s shis clean apart from two SC2120 false positives (it does not know git appends"$@"to!aliases)Not covered: the exit status on the delete path is still the last loop iteration's, since the
whileremains the last stage of a pipeline. It is unchanged by this PR and noted in #83 as non-blocking.