How no-mistakes' Force-Push Safety Mechanism Prevents Accidental Data Loss
The force-push safety mechanism prevents accidental data loss by requiring a remote-head lease and verifying through patch-id comparison that no upstream commits would be discarded before allowing any force-push operation.
The no-mistakes repository provides a CI/CD pipeline that automatically applies code fixes while rigorously protecting git history. Its force-push safety mechanism ensures that automated operations never silently overwrite foreign commits, eliminating the risk of data loss through a multi-layered verification system implemented in internal/pipeline/steps/forcepush.go.
Remote-Head Lease Verification
The safety mechanism begins by establishing a lease on the remote state. The lsRemoteSHA function executes git ls-remote to capture the current remote SHA before any push operation.
If the remote SHA matches the lastSeenSHA recorded when the pipeline last observed the repository, the force-push is permitted. This lease mechanism ensures that the pipeline only pushes when it has an up-to-date view of the remote history, preventing collisions with changes that occurred outside the pipeline's knowledge.
Fast-Path Checks
Before performing expensive content analysis, the mechanism handles two trivial cases in resolveForcePushDecision:
- New branch detection – When
ls-remotereturns no SHA for the reference, the branch does not exist remotely. The system performs a normal push instead of a force-push. - Up-to-date verification – If the remote SHA already equals the
newHeadSHAbeing pushed, the operation returns immediately without network activity.
These fast-paths optimize performance while maintaining safety invariants.
Content-Based Safety Net
When the remote has advanced beyond the lastSeenSHA through out-of-band changes, the mechanism invokes remoteCommitsNotIncorporated to perform a definitive safety check. This function implements the core protection logic:
- Fetches the remote tip into
FETCH_HEADwithout modifying remote-tracking refs. - Executes
git rev-list --cherry-pick --right-only newHeadSHA…remoteSHAto identify commits reachable from the remote but not present in the new head. - Uses patch-id comparison to detect commits representing actual code changes rather than just SHA differences.
- Excludes commits that are ancestors of the run's
baseSHA, ensuring legitimate rewrites of the pipeline's own history (such as autofix commits or amends) are not flagged as data loss.
// Inside remoteCommitsNotIncorporated – the core safety check
args := []string{
"rev-list", "--cherry-pick", "--right-only",
fmt.Sprintf("%s...%s", newHeadSHA, remoteSHA),
}
if baseSHA != "" && !git.IsZeroSHA(baseSHA) {
// Exclude the known base history so we don’t flag our own rewrites
args = append(args, "^"+baseSHA)
}
out, err := gitRun(args...)
Hard Refusal on Dropped Commits
If remoteCommitsNotIncorporated discovers any commits that would be discarded, the mechanism raises a forcePushWouldDiscardError. This error includes the offending SHAs and a clear explanation that the push would destroy upstream work, causing the pipeline to abort immediately.
// Example: deciding whether a force‑push is safe
remoteSHA, err := lsRemoteSHA(gitRun, remoteURL, ref)
if err != nil { … }
decision, err := resolveForcePushDecision(
gitRun,
remoteURL,
ref,
newHeadSHA, // the SHA we intend to push
lastSeenSHA, // the remote SHA last observed by the pipeline
baseSHA, // the base commit of the run
)
if err != nil {
// err will be *forcePushWouldDiscardError* if the push would lose data
log.Fatalf("push refused: %v", err)
}
if decision.upToDate {
fmt.Println("Remote already at the desired head – nothing to do.")
} else if decision.newBranch {
fmt.Println("Branch does not exist remotely – performing a normal push.")
} else {
fmt.Printf("Force‑push allowed (remote lease %s).\n", shortSHA(decision.remoteSHA))
}
Integration Test Coverage
The safety guarantees are verified through comprehensive tests in internal/pipeline/steps/forcepush_safety_test.go and internal/pipeline/steps/forcepush_decision_test.go:
TestCIStep_CommitAndPush_RefusesToClobberUnseenUpstreamCommitvalidates that CI autofix runs refuse to overwrite commits existing only on the remote.TestPushStep_RefusesToClobberAdvancedUpstreamBranchconfirms the push step blocks force-pushes when the remote has advanced since the last observation.TestForcePushRun_RefusesToClobberOutOfBandBranchCommitensures the combined rebase-and-push workflow respects the same safety constraints.
Summary
- The force-push safety mechanism requires a remote-head lease via
lastSeenSHAverification before permitting any force-push. - Content-based verification using
git rev-list --cherry-pickcompares patch-ids to detect commits that would be permanently lost. - The
baseSHAexclusion allows legitimate pipeline rewrites while blocking foreign commit overwrites. - A hard error (
forcePushWouldDiscardError) immediately aborts operations that would discard upstream work. - Comprehensive integration tests in
forcepush_safety_test.govalidate protection against out-of-band changes.
Frequently Asked Questions
How does the force-push safety mechanism detect commits that would be lost?
The mechanism calls remoteCommitsNotIncorporated, which runs git rev-list --cherry-pick --right-only to compare the proposed new head against the remote SHA using patch-id comparison. This identifies commits present on the remote that are not represented in the local history by their actual code changes, ensuring semantic equivalence checks rather than strict SHA matching.
Why does the safety check exclude the baseSHA from analysis?
The baseSHA represents the starting point of the current pipeline run. By excluding commits reachable from baseSHA using the ^baseSHA revision syntax, the mechanism distinguishes between legitimate rewrites of the pipeline's own autofix commits and dangerous overwrites of foreign work. This allows the pipeline to amend or rebase its own changes while protecting upstream contributions.
What specific error occurs when a force-push would discard data?
When the safety check detects commits that would be lost, it returns a forcePushWouldDiscardError. This error type includes the specific commit SHAs that would be discarded and a descriptive message explaining that the push would destroy upstream work, forcing the pipeline to abort before any network communication modifies the remote.
Where is the core force-push logic implemented?
According to the no-mistakes source code, the core implementation resides in internal/pipeline/steps/forcepush.go. This file contains the resolveForcePushDecision function that orchestrates the lease verification, fast-path checks, and content analysis, alongside the remoteCommitsNotIncorporated helper that performs the git rev-list operations.
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 →