A workflow I wish I’d learned years earlier: git bisect run fully automates “which commit introduced this bug.”

Manual bisect is already good — git bisect start, mark one bad and one good commit, and git checks out the midpoint for you to test. But if you can express “is this commit broken?” as a script that exits 0 (good) or non-zero (bad), you hand the whole search to git:

git bisect start HEAD v1.4.0        # HEAD is bad, v1.4.0 was good
git bisect run ./check.sh

git then binary-searches the range on its own and prints the first bad commit. check.sh can be a single test, a curl | grep, a build command — anything with a meaningful exit code.

Two gotchas that bite people:

  • Exit code 125 is special: it tells git “this commit is untestable, skip it” (e.g. it doesn’t compile for an unrelated reason). Use it instead of returning bad/good on commits your script can’t evaluate.
  • Guard against the flaky case — if your test is nondeterministic, bisect will happily converge on the wrong commit. Make check.sh deterministic first.

Over ~14 commits that’s 4 checkouts instead of 14. Over a 1000-commit range it’s ~10. What’s the most time this has ever saved you?

  • Alex@lemmy.ml
    link
    fedilink
    arrow-up
    3
    ·
    edit-2
    2 days ago

    If you can get your reproducer in a one liner, e.g:

    cd builds/bisect && make clean && make -j(nproc) && make run-failing-test

    then it’s super easy to pass that to /bin/sh -c “…as above…” to feed to the git bisect command