# How no-mistakes' Force-Push Safety Mechanism Prevents Accidental Data Loss

> Learn how the force-push safety mechanism prevents accidental data loss with remote-head lease and patch-id verification, ensuring no upstream commits are discarded before allowing force-pushes.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: how-to-guide
- Published: 2026-07-22

---

**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`](https://github.com/kunchenguid/no-mistakes/blob/main/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-remote` returns 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 `newHeadSHA` being 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:

1. Fetches the remote tip into `FETCH_HEAD` without modifying remote-tracking refs.
2. Executes `git rev-list --cherry-pick --right-only newHeadSHA…remoteSHA` to identify commits reachable from the remote but not present in the new head.
3. Uses patch-id comparison to detect commits representing actual code changes rather than just SHA differences.
4. 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.

```go
// 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.

```go
// 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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush_safety_test.go) and [`internal/pipeline/steps/forcepush_decision_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush_decision_test.go):

- `TestCIStep_CommitAndPush_RefusesToClobberUnseenUpstreamCommit` validates that CI autofix runs refuse to overwrite commits existing only on the remote.
- `TestPushStep_RefusesToClobberAdvancedUpstreamBranch` confirms the push step blocks force-pushes when the remote has advanced since the last observation.
- `TestForcePushRun_RefusesToClobberOutOfBandBranchCommit` ensures the combined rebase-and-push workflow respects the same safety constraints.

## Summary

- The **force-push safety mechanism** requires a remote-head lease via `lastSeenSHA` verification before permitting any force-push.
- **Content-based verification** using `git rev-list --cherry-pick` compares patch-ids to detect commits that would be permanently lost.
- The `baseSHA` exclusion 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.go`](https://github.com/kunchenguid/no-mistakes/blob/main/forcepush_safety_test.go) validate 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`](https://github.com/kunchenguid/no-mistakes/blob/main/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.