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

> Learn how the no-mistakes force-push mechanism prevents data loss. It intercepts force-pushes, verifying upstream commits aren't discarded using patch-ID equivalence.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: deep-dive
- Published: 2026-07-16

---

**The no-mistakes pipeline prevents data loss by intercepting force-push operations and verifying that no upstream commits would be discarded, using patch-ID equivalence to distinguish between rewritten and truly missing commits.**

The `kunchenguid/no-mistakes` repository implements a defensive CI/CD pipeline that protects Git repositories from accidental data loss during force-push operations. Unlike standard Git hooks, this safety mechanism performs a multi-stage verification in [`internal/pipeline/steps/forcepush.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go) to ensure upstream work is never silently overwritten.

## Re-Validating Remote State

Before executing any push, the pipeline re-establishes ground truth with the remote repository. The `lsRemoteSHA` function invokes `git ls-remote` to fetch the current SHA of the target branch, ensuring the decision is based on the latest remote state rather than cached information.

Once the remote SHA is obtained, the pipeline classifies the operation into one of three categories:

- **New branch**: If the branch does not exist remotely, the push is treated as a plain new-branch push with `newBranch: true`
- **Up-to-date**: If the remote already points at the new head, the push is flagged as a no-op with `upToDate: true`
- **Requires verification**: All other cases proceed to the safety verification logic

## Detecting Unincorporated Commits with Patch-IDs

When the remote SHA differs from the last-seen SHA, the pipeline invokes `remoteCommitsNotIncorporated` to detect out-of-band changes. This function performs a patch-ID based comparison to determine whether commits present on the remote have been incorporated into the new head.

The mechanism uses `git rev-list` with the `--cherry-pick` flag to list commits that are *right-only*—present on the remote but absent from the new head. This approach leverages **patch-ID equivalence**, meaning rebased commits that preserve the same changes are considered incorporated, while truly new remote commits are flagged as potential data loss.

```go
// internal/pipeline/steps/forcepush.go
// remoteCommitsNotIncorporated fetches the remote tip and compares histories
func remoteCommitsNotIncorporated(gitRun gitRunner, pushURL, ref, newHead, remoteSHA string) ([]string, error) {
    // Fetches remote tip without altering remote-tracking refs
    // Runs: git rev-list --cherry-pick --right-only newHead...remoteSHA
    // Returns commits present on remote but not in newHead
}

```

## Excluding Known History

The pipeline accepts a `baseSHA` parameter representing the branch base used for the current run. When provided, the safety check excludes ancestors of this base SHA from the comparison. This allows legitimate history rewrites—such as amends or auto-fixes—that the pipeline already knows about, while still catching truly unexpected upstream commits.

```go
// Excludes baseSHA ancestors to permit known rewrites
// internal/pipeline/steps/forcepush.go#L35-L38
if baseSHA != "" {
    // Exclude baseSHA history from the "would be lost" calculation
}

```

## Enforcing the Safety Boundary

If `remoteCommitsNotIncorporated` returns any commits, the pipeline immediately returns a `forcePushWouldDiscardError`. This error includes a helpful message listing sample SHAs of the commits that would be lost, converting a silent data loss scenario into a visible finding.

```go
// Handling a rejected force-push
if discardErr, ok := err.(*forcePushWouldDiscardError); ok {
    fmt.Printf("Push rejected: %s\n", discardErr.Error())
    // Show the user the commits that would be lost
    for _, sha := range discardErr.dropped {
        fmt.Printf("- %s\n", sha)
    }
    // The caller can now surface a finding or ask the user to rebase.
}

```

When no dropped commits are detected, the function returns a decision containing only the remote SHA, and the caller proceeds with the push operation.

## Implementing the Safety Check

The core decision logic resides in `resolveForcePushDecision`, which orchestrates the validation sequence:

```go
// Determining a safe push
decision, err := resolveForcePushDecision(
    gitRun,
    pushURL,          // remote URL
    "refs/heads/feature",
    newHeadSHA,       // SHA we intend to push
    lastSeenSHA,      // SHA we previously saw on the remote
    baseSHA,          // SHA of the branch base used for the run
)
if err != nil {
    // err will be of type *forcePushWouldDiscardError if the push would lose data
    log.Fatalf("cannot push: %v", err)
}
if decision.newBranch {
    fmt.Println("Branch does not exist remotely – safe to push.")
} else if decision.upToDate {
    fmt.Println("Remote already at desired HEAD – nothing to do.")
} else {
    fmt.Printf("Safe force-push anchored at %s\n", decision.remoteSHA)
}

```

## Summary

- The safety mechanism lives in [`internal/pipeline/steps/forcepush.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/forcepush.go) and anchors all force-pushes to the last observed remote SHA
- **Patch-ID comparison** via `git rev-list --cherry-pick` distinguishes between rebased commits (safe) and truly missing upstream work (unsafe)
- The `baseSHA` parameter allows legitimate history rewrites while blocking unexpected upstream commits
- Unsafe pushes return a `forcePushWouldDiscardError` containing the specific SHAs that would be lost
- New branches and up-to-date pushes bypass the heavy verification for performance

## Frequently Asked Questions

### What happens if the remote branch does not exist yet?

If `lsRemoteSHA` determines the branch does not exist remotely, `resolveForcePushDecision` immediately returns `newBranch: true`. Since there is no upstream history to overwrite, the push is considered safe and proceeds without patch-ID verification.

### How does patch-ID comparison prevent false positives during rebases?

Standard SHA comparison would flag every rebased commit as "lost" because the commit hashes change. The `remoteCommitsNotIncorporated` function uses `git rev-list --cherry-pick`, which computes patch-IDs (hashes of the diff content). If a commit's changes are present in the new head—even with a different hash—it is considered incorporated, preventing unnecessary rejections of legitimate rebases.

### Can legitimate force-pushes ever bypass the safety check?

Yes. By supplying a `baseSHA` parameter representing the known starting point of your rewrite, the pipeline excludes that history from the safety check. This permits intentional amends, squashes, or auto-fixes that the pipeline already knows about, while still blocking truly unexpected upstream commits that arrived after `baseSHA`.

### What specific error does the pipeline return when blocking a push?

The pipeline returns a `*forcePushWouldDiscardError` containing a slice of `dropped` commit SHAs. This error type provides a structured way for callers to surface findings to users, displaying the exact commits that would be discarded if the force-push proceeded.