At the end you use Git bisect

13 hours ago 2

People rant about having to learn algorithmic questions for interviews. I get it — interview system is broken, but you ought to learn binary search at least.

Anyways, yet again I came across a real life application of Algorithms. This time in the OG tool git. git bisect - Use binary search to find the commit that introduced a bug ref. And Leetcode wanted you to know it First Bad Version

We use a monorepo at work. And people tend to make hundreds, if not thousands, commit in a single repo a day. On this day, our tests started failing, and the logs weren’t enough to debug or trace the root cause. The failing method depended on a configuration file that made a remote call using a specific role to obtain a token for running the tests. At some point, that configuration had been changed — a string was updated to reference a different account — which caused the failure.

Somehow, the bad change slipped through integration tests unnoticed. It was difficult to manually find the exact file or commit that introduced the issue since many commits had been made across the repository over the past few days.

That’s when a teammate from another team — who was facing the same test failures — ran a few “magical” commands and quickly identified the exact commit where things started to break. The basic idea was simple but brilliant: pick a known good commit and a known bad one, then run a binary search to find the exact commit that caused the failure.

It took a while since each test run was time-consuming, but eventually, it pinpointed the precise commit that introduced the issue. And sure enough, after reverting that commit, everything went back to green.

Here’s a small demo repository that shows how git bisect finds the first bad commit.

File tree:

git-bisect-demo/ ├── calc.py # the library under test ├── test_calc.py # a pytest test for calc.add └── test_script.sh # wrapper used by `git bisect run`

Good version of calc.py (commit where tests pass):

def add(a, b): return a + b if __name__ == "__main__": print(add(2, 3))

Bad version of calc.py (commit that introduced the bug):

def add(a, b): # accidental string concatenation when inputs are coerced to str return str(a) + str(b) if __name__ == "__main__": print(add(2, 3))

test_calc.py (pytest):

import calc def test_add(): assert calc.add(2, 3) == 5, "Addition failed!"

test_script.sh — used by git bisect run to return exit code 0 on success and non-zero on failure:

#!/usr/bin/env bash set -e pytest -q

Example commit history (chronological):

  • Commit 1: Initial commit (good)
  • Commit 2: Small refactor (still good)
  • Commit 3: Bug introduced (bad)
  • Commits 4..10: Non-functional edits / comments (remain bad)

We can run git bisect like this:

git bisect start git bisect bad HEAD git bisect good HEAD~9 git bisect run ./test_script.sh
status: waiting for both good and bad commits status: waiting for good commit(s), bad commit known Bisecting: 4 revisions left to test after this (roughly 2 steps) [8dad374fd7c097c4fa3521c0b259e1eefe533520] Commit 5: more changes running './test_script.sh' Bisecting: 1 revision left to test after this (roughly 1 step) [b982ed9373fe235fe61c74b15faf264bc7142398] Commit 3: introduced bug running './test_script.sh' Bisecting: 0 revisions left to test after this (roughly 0 steps) [7b59759ca785572797e04f6b313bb0b735c22529] Commit 2: minor refactor running './test_script.sh' b982ed9373fe235fe61c74b15faf264bc7142398 is the first bad commit commit b982ed9373fe235fe61c74b15faf264bc7142398 Author: Kevin Date: Sun Nov 2 10:54:47 2025 -0500 Commit 3: introduced bug calc.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)

git bisect will checkout intermediate commits and run ./test_script.sh until it finds the first commit that makes the tests fail.

Read Entire Article