黎明前的代码救赎:如何用 Git Bisect 拯救我的演示[译]


那是周一凌晨 2 点,我正在疯狂地调试一个 bug,这个 bug 必须在 7 小时后的演示前解决。我实在想不通为什么会出现这个问题。但我明确知道的是:这个问题在之前的版本中并不存在。

这个项目由两个部分组成:一个运行着我用 C 语言编写的固件的设备,以及一个我用 Swift 语言编写的 iPadOS 应用程序。我相当确定这个 bug 存在于固件方面。

工作版本和有 bug 的版本之间有超过 100 次的提交,因此无法立即看出是什么更改导致了 bug。

就在这时,我想起了 git bisect。这个命令使用二分搜索算法帮助精确定位引入 bug 的确切提交。是时候让它发挥作用了。

译注:原文在此处通过动画演示了 Git Bisect 的工作过程。此处省略。

我首先将当前 HEAD 标记为 “坏的”,将最后一个已知的无故障提交标记为 “好的”:

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

然后 Git 检出这两个点之间的一个中间提交。此时二分搜索的魔力就发挥作用了。git bisect 不是逐一检查每个提交(这会花费很长时间来筛选超过 100 个提交),而是战略性地选择要测试的提交,将每次迭代的搜索空间减半。

幸运的是,这是一个我可以用脚本来验证的 bug。所以,我添加了一个脚本来检查 bug 是否存在,并让 git bisect 为每个提交运行测试。

1
git bisect run ./test_for_bug.sh

然后它就开始工作了!Git 检出不同的提交,运行我的脚本,并缩小搜索范围。

几秒钟后,Git 宣布:

1
2
3
4
5
6
b1f3d2c is the first bad commit
commit b1f3d2c5e8a9f0d4c3b2a1098765432100fedcba
Author: Mike Buss <mike@mikebuss.com>
Date: Fri Jun 9 11:23:45 2024 -0700

Added a feature that definitely won’t break anything

罪魁祸首找到了。结果发现,在我急于优化内存使用的过程中,我在传感器数据处理例程中引入了一个微妙的 bug。这个优化在大多数情况下工作得很好,但在特定条件下失败了 —— 正是我在演示场景中遇到的那种条件。

识别出有问题的提交后,修复 bug 变得容易多了。我能够精确地定位到导致问题的具体更改,并进行了必要的更正。

到了凌晨 5 点,也就是我演示前四个小时,bug 被修复了。

这次经历再次强调了一个宝贵的教训:了解你的工具和了解你的代码一样重要。git bisect 将可能需要数小时的手动调试变成了一个命令就可以完成。

在浩瀚的代码森林中,正确的工具可以是你的指南针。请记住 git bisect 的强大功能——它可能是你在下一次调试大冒险中的救命稻草。

原文链接

Debugging Till Dawn: How Git Bisect Saved My Demo