How the no-mistakes Force-Push Safety Mechanism Prevents Data Loss
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 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.
// 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.
// 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.
// 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:
// 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.goand anchors all force-pushes to the last observed remote SHA - Patch-ID comparison via
git rev-list --cherry-pickdistinguishes between rebased commits (safe) and truly missing upstream work (unsafe) - The
baseSHAparameter allows legitimate history rewrites while blocking unexpected upstream commits - Unsafe pushes return a
forcePushWouldDiscardErrorcontaining 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.
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 →