BXUP Track progress & test yourself — free
Software Engineering · Playbook · Core · ~4 min read
SOFTWARE ENGINEERING · PLAYBOOK · CORE

git bisect + AI: Find the Culprit Commit, Then Understand It

For "this used to work" bugs, the fastest path to root cause is not reading code — it is git bisect, which finds the breaking commit in log₂(N) steps with zero theorizing. AI enters after localization, where it excels: explaining the fault mechanism of a specific diff, and helping you script the bisect test itself.

Tier: Core · Workflow area: Debugging

Deterministic tool for locating, LLM for understanding — each doing the job the other is bad at.

When to use

  • A regression with a known-good past: "exports worked in the June release, broken now."
  • The breaking change is non-obvious from git log (hundreds of commits, or the symptom is far from the cause).
  • Performance regressions too — bisect works on any scriptable yes/no check, including "is p95 under 200ms".

Skip it when the bug is not a regression, when history is unbisectable (giant squash merges), or when git log -S "export_format" finds the culprit in one command — try that first.

Prerequisites

  • A repro check runnable per-commit, ideally as one command (pb-11's failing test is perfect).
  • A known-good ref and a known-bad ref (v2.14.0 good, HEAD bad).
  • Buildable history: if old commits need env juggling, budget time for it or bisect a narrower range.

The workflow

  1. Script the verdict. Turn "is it broken here?" into an exit code. Ask AI for the harness:

    Write a bash script for `git bisect run`. Broken = `pytest
    tests/exports/test_csv.py::test_unicode_headers -x` fails.
    Requirements: exit 0 if test passes, 1 if fails, 125 if the commit
    can't be built (pip install -e . fails) so bisect skips it.
    Reinstall deps only if pyproject.toml changed vs a cached hash.
    

    Sanity-check the script on both endpoints before trusting it: must exit 0 on the good ref, 1 on the bad ref. A wrong verdict script bisects you to an innocent commit with total confidence.

  2. Run the bisect.

    git bisect start HEAD v2.14.0
    git bisect run ./bisect-check.sh
    # ... "abc1234 is the first bad commit"
    git bisect reset
    

    For a flaky symptom, make the script run the test several times and fail if any run fails — bisect assumes a deterministic verdict.

  3. Hand the culprit diff to AI — with the symptom. The diff alone invites generic review; the pairing is what you want explained:

    git bisect identified this commit as the first bad one. Symptom: CSV
    export garbles non-ASCII column headers (ü -> ü) - a mojibake.
    Commit message: "perf: stream exports instead of buffering".
    [git show abc1234 output]
    
    Explain the fault MECHANISM: exactly how this change produces this
    symptom. Trace the data path. If the diff alone can't explain it,
    say what else you need to see rather than speculating.
    
  4. Confirm the mechanism, don't adopt it. A good answer names something checkable — "the old path wrote through codecs.open(..., 'utf-8'); the new streaming path writes raw bytes from str.encode() defaulting to the locale under the C locale of the worker". Verify: read the two code paths it names; reproduce with the one-line probe it implies (LC_ALL=C python -c ...). If the story doesn't survive contact with the code, feed the missing files and iterate.

  5. Fix at the mechanism level. With mechanism in hand, decide: revert, forward-fix, or both. Ask AI for the minimal forward-fix and what else the same mechanism could have broken ("what other write paths in this commit rely on locale-default encoding?") — bisect finds one symptom; the mechanism often has siblings.

  6. Keep the artifacts. Culprit hash, mechanism explanation (verified), and the verdict script go in the ticket. The script is reusable for the next regression in this area.

Pro Tip

git bisect run with a solid verdict script is fully unattended — kick it off, make tea, come back to the culprit. The engineering is all in step 1.

Tool variants

  • Any chat assistant: fine for steps 1 and 3-5; the heavy lifting is git's.
  • Terminal agent: can write the verdict script, run the whole bisect, and open the culprit — one session end-to-end; verify its endpoint sanity-check yourself.
  • IDE assistant: use for step 3 with the commit opened in the diff viewer; attach the touched files for mechanism tracing.

Verification

  • Verdict script validated on both endpoints before the bisect (the non-negotiable).
  • Culprit confirmed directly: check out abc1234, symptom present; check out abc1234~1, symptom absent.
  • The AI's mechanism explanation was verified against actual code paths or a minimal probe — not accepted on eloquence.
  • Fix tested at both levels: the pb-11-style regression test, plus one test for a "sibling" of the mechanism if step 5 found any.

Pitfalls

  • Skipping endpoint validation. The classic self-inflicted wound; ten seconds of checking saves an evening of chasing an innocent commit.
  • Bisecting with a flaky test. One spurious verdict corrupts the whole binary search. Deterministic or multi-run, always.
  • Letting AI "guess the culprit" instead of bisecting. Models are seductively good at plausible blame from git log — that is theorizing, exactly what bisect exists to replace. Localize mechanically, explain with AI.
  • Stopping at "what changed" without "why it breaks". Reverting without mechanism understanding invites the same bug back in the reland.

Restricted-environment variant

Bisect itself is local git — no restriction applies. The AI steps need only the culprit diff and the symptom, one of the smallest disclosure footprints of any AI-debugging workflow: a single sanitized git show (strip proprietary identifiers if needed) rather than whole modules. That usually fits even strict engagements' rules for sanctioned enterprise tools; failing that, local models explain single-diff mechanisms decently when the diff is under a few hundred lines. Keep commit messages with customer names out of pasted output.

Success criteria

  • Culprit found in log₂ time with zero manual commit reading (12 steps for ~4,000 commits).
  • Mechanism explained, verified, and written in the ticket — not just "reverted abc1234".
  • At least one sibling defect of the same mechanism found or ruled out.
  • Your verdict script ran unattended — you did something else while the machine searched.
This is the free reading view. Open BXUP to track your progress, run the hands-on labs, and prove it with original, exam-pattern assessments.
© Anvi Innovate · BXUP — Be Exponentially Upskilled · BXUP is an independent learning platform, not affiliated with or endorsed by AWS, Microsoft, Google, NVIDIA, IBM, Salesforce, Databricks, Oracle or Anthropic. All trademarks belong to their respective owners. · bxup.in