git bisect 二分定位 bug 实战:从上千个 commit 中找出肇事者

一、为什么二分定位有效

线性检查 1000 个提交,最坏需要 1000 次构建。二分法每次选择中间版本,把范围缩小一半,复杂度是 (O(\log_2N))。1000 个提交只需要约 10 次判断。

前提是问题具有单调性:某个提交之前是 good,之后是 bad。若 bug 被引入后又修复,或测试结果不稳定,bisect 会给出误导结果。

二、基本流程

1
2
3
git bisect start
git bisect bad HEAD
git bisect good v1.2.0

Git 会切换到中间提交。测试后标记:

1
2
3
git bisect good
# 或
git bisect bad

完成后:

1
git bisect reset

reset 会回到开始 bisect 前的分支位置。过程中不要在 detached HEAD 状态下随意提交业务代码。

三、实战:pytest 自动定位

创建 scripts/check_bug.sh

1
2
3
4
5
#!/usr/bin/env bash
set -u

python -m pip install -q -r requirements.txt || exit 125
python -m pytest -q tests/test_regression.py

赋予执行权限并运行:

1
2
3
4
5
6
7
chmod +x scripts/check_bug.sh
git bisect start
git bisect bad HEAD
git bisect good v1.2.0
git bisect run ./scripts/check_bug.sh
git bisect log
git bisect reset

退出码有特殊含义:0 表示 good,1~127 表示 bad,125 表示当前提交无法判断、应跳过。依赖安装失败通常应返回 125,而不是把环境问题判成代码 bug。

四、编译失败和性能回归

编译检查脚本:

1
2
3
4
#!/usr/bin/env bash
set -u
make clean >/dev/null 2>&1 || true
make -j"$(nproc)"

性能脚本应使用固定输入,并避免把机器噪声当成回归:

1
2
3
4
5
6
7
8
9
10
import subprocess
import sys

baseline = 0.250
output = subprocess.check_output(
[sys.executable, "-m", "pytest", "-q", "tests/test_benchmark.py"],
text=True,
)
seconds = float(output.strip())
sys.exit(0 if seconds <= baseline * 1.20 else 1)

性能阈值要留出余量,最好重复多次取中位数,并在固定硬件、固定容器和固定 CPU governor 下比较。

五、高级技巧

git bisect log 可以保存过程,之后用 git bisect replay 重放。已知某些提交无法构建时使用:

1
git bisect skip

最后找到候选提交后:

1
2
3
git show --stat <commit>
git show <commit> -- path/to/file
git blame -L 20,60 path/to/file

如果确认是独立错误,可创建修复提交;不要因为找到肇事者就直接回滚整个分支。git revert <commit> 会生成反向提交,适合公共分支。

六、踩坑记录

Merge commit 可能让搜索路径复杂。默认 bisect 会沿提交图查找,不一定符合“业务上线顺序”。可以选择一个明确的主线 good 点,并记录发布时间。

测试不稳定是最常见问题。先单独运行测试 20 次,确认失败概率,再进行 bisect。跨平台构建差异也会造成误判,应在与生产一致的容器中执行脚本。

七、小结

标准模板是:

1
2
3
4
5
git bisect start
git bisect bad <bad>
git bisect good <good>
git bisect run <deterministic-check>
git bisect reset

团队应维护稳定、快速、可重复的回归测试;只有这样,二分工具才能把十几分钟的故障定位压缩到几分钟。


git bisect 二分定位 bug 实战:从上千个 commit 中找出肇事者
https://blog.calcguide.tech/2026-08-10-git-bisect二分定位bug实战/
作者
王争气
发布于
2026年8月10日
许可协议