Git Bisect——用二分法快速定位问题提交

1、问题场景

某天你发现一个 bug,但不知道是从哪个提交引入的。代码仓库有几百个提交,一个一个 checkout 检查显然不现实。

这时 git bisect 就派上用场了——它使用二分查找法,自动帮你缩小范围,快速定位到引入 bug 的那次提交。

2、基本用法

假设当前版本有问题,而你知道 v1.0 标签的版本是正常的。在 n 个提交中,用二分法只需大约 log₂n 步就能定位。比如 100 个提交只需约 7 步。

启动 bisect

git bisect start

标记坏提交(当前版本)

git bisect bad HEAD

标记好提交(已知正常的版本)

git bisect good v1.0

执行后,Git 会自动检出中间位置的一个提交。你需要测试这个版本:

  • 如果有 bug → git bisect bad
  • 如果正常 → git bisect good

Git 会继续缩小范围,重复几次后,最终告诉你:

a1b2c3d4 is the first bad commit

结束 bisect

git bisect reset

这会让仓库回到 bisect 之前的状态。

3、自动化 bisect

如果你可以通过脚本判断 bug 是否存在,可以全自动运行:

git bisect start HEAD v1.0
git bisect run ./test-script.sh

test-script.sh 的退出码决定了结果:

  • 退出码 0 → 这个提交是好的(good)
  • 退出码 1~127(不含 125)→ 这个提交是坏的(bad)
  • 退出码 125 → 这个提交无法测试,跳过(skip)

实际例子

比如某个单元测试失败了,你知道在 v1.0 时是通过的:

git bisect start HEAD v1.0
git bisect run npm test -- --testPathPattern=UserLogin

Git 会自动二分查找,直到找到导致测试失败的第一个提交。

4、高级用法

跳过无法测试的提交

有些提交可能无法编译或无法运行测试:

git bisect skip

Git 会跳过这个提交,选择附近的另一个提交继续测试。

使用术语替换

如果你觉得 good/bad 不够直观,可以用其他术语:

git bisect start --term-old=fast --term-new=slow
git bisect slow   # 当前版本慢(有性能问题)
git bisect fast v1.0  # v1.0 是快的

查看 bisect 日志

git bisect log

可以查看整个 bisect 过程,便于复盘或分享给同事。

可视化 bisect 过程

git bisect visualize

这会打开 gitk(如果安装了),以图形方式展示当前的二分查找范围,让你直观了解还有多少提交需要检查。

5、实战技巧

确认范围

在启动 bisect 前,确保你知道一个”好”的提交和一个”坏”的提交。如果不确定最早的坏提交在哪,可以从 HEAD~50 或某个较早的标签开始。

选择合适的测试方法

  • 简单 bug:手动测试即可,用 git bisect good/bad
  • 可脚本化:写自动化脚本,用 git bisect run
  • 编译错误:判断能否成功编译即可

中途保存进度

如果 bisect 过程很长,可以记录状态:

git bisect log > bisect.log
# 之后恢复
git bisect replay bisect.log

6、总结

git bisect 是 Git 中最被低估的功能之一。当你面对”不知道从哪个提交开始出问题”的场景时,它能节省大量时间。

适用场景

  • 回归 bug 定位
  • 性能退化定位
  • 编译错误定位
  • 任何”之前正常,现在不正常”的问题

记住一个口诀:二分法定位,good 好 bad 坏,最多 log₂n 步就能找到元凶。

每天前进一小步,就是一个新的高度!

作者:唐明

出处:/post/git-bisect

版权:本站使用"CC BY 4.0"创作共享协议,转载请在文章明显位置注明作者及出处。

关注微信公众号

DevOps持续交付公众号ID:devopscd