allod change cleanup deletes a branch when has_unpushed_commits cannot tell whether it has unpushed commits #127
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/tools#127
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Make
has_unpushed_commitsdistinguish "no unpushed commits" from "cannot tell", soallod change cleanupstops deleting a branch whose commits it was never able to check.Primary goals:
cleanupdeletes a worktree and itsagent/*branch, so it should proceed only when it can show the commits exist onorigin, never because a check it could not perform came back false.return 1, which is the silent fallbackarchitecture.mdprinciple 11 forbids.recordandlisthonest — the same collapse makesrecordsay "no unpushed commits to push" when it cannot tell, and makesallod change listreportcleanfor a worktree holding commits that exist nowhere else.Current state
allod:203-228. Four paths answer "no unpushed commits" when the honest answer is "cannot determine":Three consumers read it.
change_cleanup:501-503is the destructive one: past that check it runsworktree remove(:506) andbranch -D(:508).change_record:354-357reportsdie 4 "nothing to commit and no unpushed commits to push", which is misleading rather than harmful.allod change list, added in PR allod/tools#125, reportsclean.Reproduction and consequence
Verified on git 2.51.2. A repo with no
originremote — so every commit on the branch is by definition unique local work — reaches:223:cleanupexits 0, removes the worktree, and printsDeleted branch agent/local-only. The commit is then reachable from no ref: the branch reflog died with the branch, the worktree's HEAD reflog died with its private git dir, and the main checkout's reflog never saw the commit. Recovery isgit fsck --lost-founduntilgit gcprunes the object.allod change listreports the same worktree ascleanbeforehand, so both halves agree and both are wrong.The
:208detached path is not the dangerous one and is already documented inallod/strategydev-plans/allod-change-always-isolate.md:cleanupcallscurrent_branch_or_die(allod:495) first and refuses detached worktrees before reaching this check, which makes that path a reporting hazard rather than data loss.:220is narrow for the reason recorded in issue allod/tools#126 — git repairsrefs/remotes/origin/HEADon any fetch.:223is the reachable one.Scope
In:
allod:203-228and its three consumers at:354,:501, andchange_list;tests/allod-change.sh.The default: give the helper a third result — commits unpushed, none unpushed, or base undeterminable — and handle the third explicitly.
cleanuprefuses it, naming the missingoriginor unresolvable base and pointing atgit -C <repo> branch -D <branch>as the deliberate manual override, per principle 4 (rails are overridden with standard git, not with a bypass flag).recordsays it could not determine what is unpushed rather than asserting there is nothing.listgains a distinct state word for it.list's binding contract from PR allod/tools#125 — it reportscleanif and only ifcleanupon that path would succeed — must keep holding, so whatevercleanupstarts refusing,liststops callingcleanin the same change. The per-state agreement tests intests/allod-change.shalready assert that pairing and extend to the new state.Considered and rejected: having
cleanuprequire an upstream branch outright. It refuses the same cases but reports every one of them as "no upstream", losing the distinction between a repo with no remote, an unresolvable default branch, and a genuine failure to runrev-list, which is the information the operator needs to act.Out: the
origin/HEADresolution defect behind:220, which is issue allod/tools#126 and is a different contract in a different file.Found while tracing consumers for allod/tools#126.
completed