最后使用Git bisect。
At the end you use `git bisect`

原始链接: https://kevin3010.github.io/git/2025/11/02/At-the-end-you-use-git-bisect.html

## 算法在现实世界的应用:Git Bisect 与二分查找 尽管人们对面试中偏重算法的问题感到沮丧,但它们在最近的一次调试工作中展现出了实际价值。一个团队面临着大型单仓库中频繁提交导致测试失败的问题,使得传统的调试方法变得困难。问题源于一个引用了错误账户的配置更改,绕过了最初的集成测试。 手动定位问题提交是不切实际的。幸运的是,一位同事使用了 `git bisect` 命令,该命令利用 **二分查找** 算法有效地识别引入错误的提交。通过定义一个已知的良好提交和一个不良提交,`git bisect` 系统地检查中间提交,并运行测试以缩小范围。 虽然每次测试运行都需要时间,但该过程迅速隔离了有问题的提交。回滚该提交解决了问题。这表明像二分查找这样看似学术的算法,是日常软件开发中一种强大的工具,尤其是在像 Git 这样的版本控制系统中,可以节省大量的调试时间和精力。

相关文章

原文

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.

联系我们 contact @ memedata.com