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

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 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.

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.

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.

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.

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 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.

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. 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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →