push --force: the lease does not protect commits that madt_status fetched #635
Labels
No labels
breaking
bug
documentation
enhancement
epic
good first issue
help wanted
refactoring
resolution/duplicate
resolution/invalid
resolution/wontfix
security
severity/critical
severity/high
severity/low
severity/medium
status/abandoned
status/blocked
status/needs-decision
status/needs-info
status/needs-verification
testing
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sixfold-space/madtea#635
Loading…
Add table
Add a link
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?
What
ADR 0029 classifies
push --forceas machine-proof. Its reason: "git refuses the push if the remote ref moved since the last fetch, so no unseen work is clobbered".That reason does not hold when madtea itself fetches:
internal/service/git/push.go:145runs--force-with-leasewith no expected value. In that form, git compares the remote branch with the local remote-tracking reforigin/<branch>.madt_statusruns a realgit fetchon every call (internal/service/git/status.go:18). That fetch movesorigin/<branch>.Failure sequence
madt_statusfetches.origin/Bnow points at X. The local branch B does not contain X.madt_push force=truepushes B. The remote ref equalsorigin/B, so the lease passes.X still exists in the local object store and in the
origin/Breflog, but nothing tells the user. I derived this sequence from the manual and the code. I have not reproduced it yet.Possible fixes
--force-if-includes. The manual gives it as the mitigation: git refuses the forced update unless the remote-tracking tip was integrated locally.--force-with-lease.Acceptance
push --force.Decision:
push --forceis omitted from both surfaces,madtea pushandmadt_push.git needs force only when the new tip does not contain the old remote tip. So every force push removes at least one commit from the remote branch. A lease, with or without
--force-if-includes, proves only that a copy exists in the local clone. That is not enough: the work must still exist on the remote. Sopush --forcedoes not meet the machine-proof exception in ADR 0029, and it falls under omission.A force-free path already exists for a base that moved under a pushed branch.
madtea orchestrate reconcilemerges the base into the PR head (internal/service/orchestrate/reconcile.go:299), then pushes throughrealGitOps.Push(internal/service/orchestrate/types.go:205), which runsgit push -u origin <branch>with no force (internal/git/push.go:22).The fix needs a new decision record that moves
push --forcefrom machine-proof to omit in the ADR 0029 table. #637 is a second force path, through a leading+in the branch value.