黎明前的代码救赎:如何用 Git Bisect 拯救我的演示[译]
那是周一凌晨 2 点,我正在疯狂地调试一个 bug,这个 bug 必须在 7 小时后的演示前解决。我实在想不通为什么会出现这个问题。但我明确知道的是:这个问题在之前的版本中并不存在。
这个项目由两个部分组成:一个运行着我用 C 语言编写的固件的设备,以及一个我用 Swift 语言编写的 iPadOS 应用程序。我相当确定这个 bug 存在于固件方面。
工作版本和有 bug 的版本之间有超过 100 次的提交,因此无法立即看出是什么更改导致了 bug。
就在这时,我想起了 git bisect。这个命令使用二分搜索算法帮助精确定位引入 bug 的确切提交。是时候让它发挥作用了。
译注:原文在此处通过动画演示了 Git Bisect 的工作过程。此处省略。
我首先将当前 HEAD 标记为 “坏的”,将最后一个已知的无故障提交标记为 “好的”:
1 | git bisect start |
然后 Git 检出这两个点之间的一个中间提交。此时二分搜索的魔力就发挥作用了。git bisect 不是逐一检查每个提交(这会花费很长时间来筛选超过 100 个提交),而是战略性地选择要测试的提交,将每次迭代的搜索空间减半。
幸运的是,这是一个我可以用脚本来验证的 bug。所以,我添加了一个脚本来检查 bug 是否存在,并让 git bisect 为每个提交运行测试。
1 | git bisect run ./test_for_bug.sh |
然后它就开始工作了!Git 检出不同的提交,运行我的脚本,并缩小搜索范围。
几秒钟后,Git 宣布:
1 | b1f3d2c is the first bad commit |
罪魁祸首找到了。结果发现,在我急于优化内存使用的过程中,我在传感器数据处理例程中引入了一个微妙的 bug。这个优化在大多数情况下工作得很好,但在特定条件下失败了 —— 正是我在演示场景中遇到的那种条件。
识别出有问题的提交后,修复 bug 变得容易多了。我能够精确地定位到导致问题的具体更改,并进行了必要的更正。
到了凌晨 5 点,也就是我演示前四个小时,bug 被修复了。
这次经历再次强调了一个宝贵的教训:了解你的工具和了解你的代码一样重要。git bisect 将可能需要数小时的手动调试变成了一个命令就可以完成。
在浩瀚的代码森林中,正确的工具可以是你的指南针。请记住 git bisect 的强大功能——它可能是你在下一次调试大冒险中的救命稻草。