# How the Force Push Safety Mechanism in no-mistakes Prevents Overwriting Remote Commits

> Learn how the force push safety mechanism in no-mistakes prevents overwriting remote commits. It verifies remote commits before allowing a force push, protecting your work.

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

---

**The force push safety mechanism in no-mistakes prevents overwriting remote commits by verifying that every commit on the remote tip exists in the new head (compared by patch-id) before allowing a force push, aborting the operation if any unincorporated commits would be lost.**

The `kunchenguid/no-mistakes` repository implements a robust safeguard against silent data loss during Git force pushes. This mechanism ensures that CI/CD pipelines never accidentally discard upstream work caused by out-of-band pushes or stale rebase operations. The implementation resides primarily in [`internal/pipeline/steps/forcepush.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go) and enforces a strict validation protocol before executing any destructive push operations.

## Three-Stage Safety Validation

The force push safety mechanism operates through a deterministic three-stage pipeline that validates the remote state against the pipeline's historical observations and the proposed new head.

### Stage 1: Determining the Remote's Current Tip

The guard begins by fetching the remote reference's current SHA using `lsRemoteSHA`. This function executes `git ls-remote` to resolve the exact state of the remote ref before the pipeline attempts any modifications.

If the reference does not exist on the remote, the operation is classified as a **new branch push** and proceeds normally without force flags. If the remote already points at the exact SHA being pushed, the branch is marked as **up-to-date** and requires no action.

```go
current, err := lsRemoteSHA(gitRun, pushURL, ref)   // → https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go#L66-L71

```

### Stage 2: Validating Against Pipeline History

The mechanism compares the current remote SHA against the `lastSeenSHA`—the remote head recorded by the pipeline after its previous push. When these values match, the remote has not changed since the pipeline last observed it, making a force push safe because it only rewrites history the pipeline itself produced.

```go
if lastSeenSHA != "" && current == lastSeenSHA {
    return forcePushDecision{remoteSHA: current}, nil   // https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go#L76-L80
}

```

### Stage 3: Detecting Unincorporated Commits

When the remote has diverged from the `lastSeenSHA`, the guard invokes `resolveForcePushDecision` to analyze the commit graph. This stage calls `remoteCommitsNotIncorporated` to identify commits that would be permanently lost by the force push.

The function executes `git rev-list --cherry-pick --right-only newHeadSHA...remoteSHA` to compare commits by **patch-id**, ensuring that rebased commits with new SHAs but identical changes are considered incorporated. It excludes ancestors of `baseSHA` to allow intentional rewrites of the pipeline's own history while protecting upstream work.

```go
args := []string{"rev-list", "--cherry-pick", "--right-only", newHeadSHA + "..." + remoteSHA} // https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go#L34-L35
// optionally exclude ^baseSHA … https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go#L36-L38

```

If the command returns any commits, the function returns a `forcePushWouldDiscardError`, aborting the push and surfacing a detailed error message indicating which commits would be dropped.

```go
if len(dropped) == 0 {
    return forcePushDecision{remoteSHA: current}, nil
}
return forcePushDecision{}, &forcePushWouldDiscardError{ref: ref, remoteSHA: current, dropped: dropped}
// https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go#L90-L94

```

## Guarded Push Execution

The push step in [`internal/pipeline/steps/push.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/push.go) consumes the decision struct returned by the safety mechanism. It never executes a blind `--force`; instead, it uses `--force-with-lease=<remoteSHA>` to ensure Git rejects the push if the remote has moved since the check occurred.

```go
decision, err := resolveForcePushDecision(gitRun, pushURL, ref, newHeadSHA, lastSeenSHA, baseSHA)
if err != nil {
    // abort – remote would lose commits
    return fmt.Errorf("push aborted: %w", err)
}

if decision.newBranch {
    // ordinary push for a brand‑new branch
    gitRun("push", pushURL, fmt.Sprintf("%s:%s", newHeadSHA, ref))
} else if decision.upToDate {
    // nothing to do – already at the target SHA
    return nil
} else {
    // guarded force‑push anchored to the remote SHA we observed
    gitRun("push", "--force-with-lease="+decision.remoteSHA,
            pushURL, fmt.Sprintf("%s:%s", newHeadSHA, ref))
}

```

## Error Handling and User Feedback

When the safety mechanism detects unincorporated commits, it returns a formatted error that clearly identifies the reference, the remote SHA, and the number of commits at risk:

> "refusing to force‑push `refs/heads/feature`: remote head `0e1c55…` carries 1 commit(s) the pipeline never incorporated …"

This explicit failure mode eliminates the silent data loss scenarios that previously caused issues #281 and #305 in the repository's issue tracker.

## Summary

- **`lsRemoteSHA`** fetches the current remote tip to establish the baseline state.
- The **`lastSeenSHA`** comparison prevents force pushes when the remote has changed unexpectedly.
- **`remoteCommitsNotIncorporated`** uses patch-id comparison to detect commits that would be lost, allowing rebased but equivalent changes while blocking true data loss.
- The mechanism enforces **`--force-with-lease`** rather than naked `--force`, adding a server-side double-check.
- Failed validations return **`forcePushWouldDiscardError`** with detailed context instead of allowing silent corruption.

## Frequently Asked Questions

### What happens when the remote branch has new commits?

When `resolveForcePushDecision` detects that the remote SHA differs from `lastSeenSHA` and contains commits not present in the new head (compared by patch-id), it returns a `forcePushWouldDiscardError`. This aborts the pipeline immediately before any network push occurs, preventing the new commits from being overwritten.

### How does no-mistakes handle rebased commits?

The safety mechanism uses `git rev-list --cherry-pick` with patch-id comparison rather than strict SHA equality. This means commits that were rebased (giving them new SHAs) but contain identical changes are considered incorporated and will not trigger the safety guard, allowing legitimate history rewriting while blocking actual data loss.

### What error message appears when a force push is blocked?

The system returns a structured error formatted by `forcePushWouldDiscardError.Error()`, typically reading: "refusing to force‑push `<ref>`: remote head `<sha>` carries `<n>` commit(s) the pipeline never incorporated." This message includes the specific reference name and short SHA of the remote tip that contained the unincorporated work.

### Can I bypass the force push safety guard?

No. The guard is embedded in the core push step logic in [`internal/pipeline/steps/push.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/push.go). Because the pipeline exclusively uses the decision returned by `resolveForcePushDecision`, there is no configuration flag or CLI argument that overrides the safety check without modifying the source code. This design ensures no-mistakes pipelines never accidentally discard upstream commits.