How `resolveForcePushDecision` and `lastSeenSHA` Prevent Accidental Force-Pushes in no-mistakes
The no-mistakes pipeline prevents accidental force-pushes by using resolveForcePushDecision to compare the current remote HEAD against a stored lastSeenSHA, rejecting any push where the remote has advanced since the pipeline last checked.
The no-mistakes repository implements a fail-closed safety mechanism to protect shared Git history from destructive overwrites. By anchoring force-push decisions to a previously observed remote state stored in lastSeenSHA, the system ensures developers cannot accidentally overwrite commits pushed by others. This protection centers on the resolveForcePushDecision function in internal/pipeline/steps/forcepush.go, which implements a lease-based verification system.
The resolveForcePushDecision Safety Check
The ** resolveForcePushDecision** function serves as the gatekeeper for all force-push operations in the pipeline. Before allowing any destructive rewrite of remote history, it performs a fresh git ls-remote call to obtain the actual current tip of the target branch. This real-time verification ensures the pipeline's view of the remote has not become stale since the last check.
The function accepts several key parameters: gitRun (the command executor), pushURL, ref (the branch reference), newHeadSHA (the local commit being pushed), lastSeenSHA (the previously observed remote state), and baseSHA (the PR base commit for additional safety checks).
// Example: deciding whether a force‑push is allowed
decision, err := resolveForcePushDecision(
gitRun, // wrapper around exec.Command
pushURL, // remote URL for the push
ref, // e.g. "refs/heads/feature"
newHeadSHA, // the SHA we want to push
lastSeenSHA, // remote head the pipeline last saw
baseSHA, // base commit of the PR (used for extra safety)
)
if err != nil {
// handle error – push will be aborted
}
if decision == forcePushAllowed {
// safe to push (or force‑push with lease)
}
How lastSeenSHA Acts as a Push Lease
lastSeenSHA is not the SHA of the latest local commit; it is a snapshot of the remote tip taken earlier in the pipeline execution and stored in runs.last_seen_sha. This value represents the pipeline's last known good state of the remote branch.
By anchoring the push decision to this stored value, the system implements a compare-and-swap style lease. The pipeline refuses to force-push unless it can prove the remote has not moved since it was last examined. This prevents the classic "force-push over someone else's work" scenario where a stale view of the remote would otherwise allow destructive rewrites.
Three Conditions That Permit Force-Pushing
The function allows force-pushes only under three specific safe conditions:
- New branch creation – The ref does not exist remotely, so a force-push is harmless.
- Unchanged remote – The
currentremote HEAD equalslastSeenSHA, proving no one has pushed since the pipeline last checked. - Already up-to-date – The
newHeadSHAalready matches the current remote HEAD, meaning no rewrite is actually needed.
If any of these conditions are met, the function returns forcePushAllowed. Otherwise, it returns forcePushRejected with an error explaining that the remote head has changed.
// Inside `resolveForcePushDecision` (simplified)
current, err := gitRun.Run("ls-remote", pushURL, ref)
if lastSeenSHA != "" && current == lastSeenSHA {
// Remote unchanged – safe to force‑push
return forcePushAllowed, nil
}
if current == newHeadSHA {
// Already up‑to‑date – no force‑push needed
return forcePushAllowed, nil
}
return forcePushRejected, fmt.Errorf("remote head advanced from %s to %s", lastSeenSHA, current)
Pipeline Integration and Fail-Closed Behavior
The safety mechanism extends across multiple pipeline steps to ensure consistent protection:
- CI Fix Step (
internal/pipeline/steps/ci_fix.go): Also callsresolveForcePushDecisionwhen pushing automated fixes, ensuring the same safety checks apply after an automated commit. - Push Step (
internal/pipeline/steps/push.go): Uses the decision outcome to choose between a normal push, a safe force-push with lease anchored tolastSeenSHA, or an abort with a clearly reported finding.
Together, these checks enforce a fail-closed policy: any ambiguous or out-of-date remote state results in a rejected push rather than a silent overwrite. The unit tests in internal/pipeline/steps/forcepush_decision_test.go verify both allowed and rejected cases to maintain this safety invariant.
Summary
resolveForcePushDecisionininternal/pipeline/steps/forcepush.goacts as the central gatekeeper for force-push safety.lastSeenSHAstores the pipeline's last observed remote state, functioning as a lease token that must match the current remote HEAD.- The system allows force-pushes only for new branches, unchanged remotes, or already-up-to-date states.
- Both the CI fix step and push step reuse this logic, ensuring consistent protection across all push operations.
- When the remote has advanced beyond
lastSeenSHA, the function returnsforcePushRejectedto prevent overwriting others' work.
Frequently Asked Questions
What exactly is lastSeenSHA in the no-mistakes pipeline?
lastSeenSHA is the commit hash of the remote branch tip as observed earlier in the pipeline execution, stored in the database field runs.last_seen_sha. It is not the local commit SHA, but rather a snapshot of the remote state used to detect if someone else has pushed to the branch since the pipeline began.
How does resolveForcePushDecision detect out-of-band pushes?
The function runs git ls-remote to fetch the current remote HEAD and compares it against the stored lastSeenSHA. If these values differ, it indicates the remote has advanced out-of-band (for example, by another developer pushing directly), and the function rejects the force-push to prevent overwriting those new commits.
What happens when resolveForcePushDecision rejects a push?
When the remote HEAD has advanced beyond lastSeenSHA, the function returns forcePushRejected along with an error message indicating the remote head has changed. The calling code in push.go or ci_fix.go then aborts the operation and reports the conflict, forcing the developer to pull the latest changes and reconcile before retrying.
Is this mechanism only used for force-pushes or all pushes?
While specifically designed to prevent dangerous force-pushes, the decision logic is evaluated for push operations that might require rewriting history. Normal fast-forward pushes that don't require force flags may proceed through different pathways, but any operation that could overwrite remote history must pass the resolveForcePushDecision check first.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →