# How Rebase Safety in no-mistakes Detects Bundled Local Default Branch Commits

> Learn how no-mistakes rebase safety detects bundled local default branch commits. Prevent accidental inclusion of un-pushed work with explicit user approval.

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

---

**The `detectBundledLocalDefaultCommits` function in [`internal/pipeline/steps/rebase.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/rebase.go) prevents accidental inclusion of un-pushed default branch work by verifying that the local default tip is reachable from the feature branch but not present on the remote default, forcing explicit user approval before proceeding.**

The `no-mistakes` repository provides automated gating for Git workflows, ensuring that contributors do not accidentally bundle commits from their local default branch into feature pull requests. When executing a rebase, the tool must distinguish between legitimate feature work and un-pushed changes that exist only on the contributor's local `main` or `master`. This rebase safety mechanism relies on a precise detection algorithm that compares the local default tip against the remote default across the working and gate repositories.

## The Detection Algorithm

The core logic resides in the `detectBundledLocalDefaultCommits` function within [`internal/pipeline/steps/rebase.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/rebase.go). This function executes a ten-step verification process to identify bundled commits with certainty.

### Step 1: Skip Trivial Cases

The function immediately returns `nil` if the current branch is the default branch itself or if the repository is empty. In these scenarios, no bundling is possible because the branch context prevents ambiguous commit inclusion.

### Step 2: Locate the Local Default Tip

The code runs `git rev-parse refs/heads/<default>` inside the working repository at `sctx.Repo.WorkingPath` to identify the commit hash that may contain un-pushed work. This establishes the local reference point for comparison.

### Step 3: Verify Remote Default Exists

Before attempting comparison, the function confirms that `origin/<default>` resolves successfully within the gate repository at `sctx.WorkDir`. This ensures the remote reference is available for ancestry checks.

### Step 4: Validate Object Presence

The algorithm verifies the local tip exists in the gate repository's object store by executing `git rev-parse <localTip>`. This step guarantees that the commits being evaluated are actually present in the branch history.

### Step 5: Check for Already-Pushed Commits

Using an `isAncestor` check, the function determines if the local tip is already reachable from `origin/<default>`. If true, the commits exist on the remote and the function returns `nil`, allowing the rebase to proceed normally.

### Step 6: Confirm Branch Ancestry

The function verifies that the feature branch actually contains the local default tip by checking `isAncestor(localTip, HEAD)`. If the local tip is not an ancestor of the current branch, no bundling is occurring and the function exits.

### Step 7: List Un-Pushed Commits

When the previous checks confirm bundling, the code executes `git log origin/<default>..localTip` to enumerate the specific commits that exist locally but not on the remote. This generates a human-readable list for the warning message.

### Step 8: Collect Changed Files

To quantify the scope of bundled work, the function runs `git diff --name-only origin/<default> localTip` to identify affected files. The first file in this list is included in the finding details.

### Step 9: Build the Finding

The function constructs a JSON `Findings` object with **warning** severity, `ActionAskUser`, and a descriptive message including the commit list and file count. This prepares the data for user notification.

### Step 10: Return the Outcome

The step returns a `&pipeline.StepOutcome` with `NeedsApproval: true` and `AutoFixable: false`, halting the pipeline until the user explicitly approves the action or resolves the underlying issue.

## Code Implementation Example

When implementing the rebase step in your own automation, you can expect the following behavior when bundled commits are detected:

```go
// sctx is a *pipeline.StepContext prepared by the daemon.
// Assume sctx.Run.Branch = "refs/heads/feature"
step := &steps.RebaseStep{}
outcome, err := step.Execute(sctx)
if err != nil {
    log.Fatalf("rebase step failed: %v", err)
}
if outcome != nil && outcome.NeedsApproval {
    // The branch bundles un‑pushed local‑default commits.
    fmt.Println("⚠️  Rebase blocked:")
    fmt.Println(outcome.Findings) // JSON with warning & commit list
}

```

When the repository contains a feature branch built on top of an un-pushed local `main` commit, the outcome includes a JSON structure similar to:

```json
{
  "items": [
    {
      "severity": "warning",
      "file": "unrelated_a.txt",
      "description": "branch carries 1 commit(s) that exist on your local main branch but were never pushed to origin/main; rebasing would bundle this unrelated work (2 file(s)) into the PR:\n- unrelated backend work (77 files)\n\nPush main to origin, or rebase your branch onto origin/main, before gating.",
      "action": "ask-user"
    }
  ],
  "summary": "branch bundles 1 unpushed main commit(s)"
}

```

## Test Coverage

The detection logic is verified by [`rebase_local_default_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/rebase_local_default_test.go), which creates a controlled scenario where a feature branch deliberately includes an un-pushed local default commit. The test confirms that `detectBundledLocalDefaultCommits` returns the expected `NeedsApproval` outcome.

```go
func TestRebaseStep_DetectsUnpushedLocalDefaultBranchCommits(t *testing.T) {
    // (setup creates a working repo with an un‑pushed commit on local main,
    // clones the upstream, creates a feature branch that includes that commit,
    // and runs the RebaseStep.)

    outcome, err := (&steps.RebaseStep{}).Execute(sctx)
    require.NoError(t, err)
    require.NotNil(t, outcome)
    assert.True(t, outcome.NeedsApproval)
    assert.False(t, outcome.AutoFixable)
    assert.Contains(t, outcome.Findings, "unrelated backend work")
}

```

This test ensures the safety mechanism works correctly for both standard rebases and force-push scenarios.

## Safety Guarantees

The rebase safety mechanism provides three critical protections:

- **Best-effort verification** – The detection only triggers when the code can definitively prove that the branch contains un-pushed default-branch commits, preventing false positives.
- **Non-automatic resolution** – Because bundled work belongs to a different work-stream, the pipeline sets `AutoFixable: false` and requires manual intervention to push the default branch or rebase onto the fresh remote default.
- **Comprehensive test coverage** – The behavior is validated across multiple scenarios in [`rebase_local_default_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/rebase_local_default_test.go) and [`rebase_force_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/rebase_force_test.go), ensuring reliability in production environments.

## Summary

- The `detectBundledLocalDefaultCommits` function in [`internal/pipeline/steps/rebase.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/rebase.go) implements a ten-step verification process to identify un-pushed default branch commits.
- The algorithm uses `isAncestor` checks and `git rev-parse` operations across both the working and gate repositories to confirm bundling.
- When detected, the step returns `NeedsApproval: true` with a JSON finding containing commit details and file counts, forcing explicit user review.
- The mechanism is **best-effort** and **non-auto-fixable**, requiring users to push their default branch or rebase onto the remote default before proceeding.
- Test coverage in [`rebase_local_default_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/rebase_local_default_test.go) ensures the detection works for both normal and force-push rebase operations.

## Frequently Asked Questions

### What triggers the bundled commit detection in no-mistakes?

The detection triggers when a feature branch contains commits that exist on the local default branch (e.g., `main`) but are not present on `origin/main`. Specifically, when `isAncestor(localTip, HEAD)` returns true but `isAncestor(localTip, origin/default)` returns false, the system identifies bundled work and halts the pipeline.

### Can the no-mistakes pipeline automatically fix bundled local default branch commits?

No. The step explicitly sets `AutoFixable: false` because the un-pushed work represents a separate work-stream that requires human decision-making. Users must either push their local default branch to the remote or rebase their feature branch onto the updated remote default before the gate will allow the rebase to proceed.

### Where is the rebase safety detection logic implemented in the no-mistakes codebase?

The primary implementation resides in [`internal/pipeline/steps/rebase.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/rebase.go), specifically within the `detectBundledLocalDefaultCommits` function. Test coverage demonstrating this behavior is located in [`internal/pipeline/steps/rebase_local_default_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/rebase_local_default_test.go), with additional force-push scenarios tested in [`rebase_force_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/rebase_force_test.go).

### How does the detection algorithm prevent false positives?

The algorithm employs multiple verification layers: it skips empty repositories and default branches, confirms the remote default exists, validates the local tip is actually in the branch ancestry, and ensures the local tip is not already reachable from the remote default. Only when all these conditions confirm unique local commits does it generate a warning.