使用 Git bisect 快速代码定位问题

245 阅读3分钟

前言

在开发过程中,有时会遇到一些 Bug 隐藏在多个 commit 之间,定位问题变得非常耗时。最近我遇到了类似的情况,它可以用 git bisect 解决,我和大家分享这个高效的调试工具。

问题背景

事情是这样的,我在本地开发了一个分支,开发了一段时间后,发现某个简单操作会导致程序崩溃。我本以为是自己代码的问题,于是尝试逐个回退 commit 进行排查。

我的分支一共只有 5 个 commit,回退到最后发现问题依然存在,我才意识到,这个问题可能是由其他同学提交的代码引起的。

仓库最近几天新增了将近 100 个 commit,如果继续逐个排查,显然会非常浪费时间。这时,我需要一个更高效的方式来找到问题所在。

有没有办法快速查出是哪一个 commit 引入了问题?答案就是 git bisect

什么是 Git Bisect?

git bisect 是 Git 自带的一个命令,使用二分查找的方式,在指定范围内快速定位引入问题的 commit。

它的效率很高,因为二分查找的时间复杂度是 logn。比如仓库里有 100 个 commit,用 git bisect 理论上只需要测试大约 6 次就能找到问题所在。这比逐个回退检查的方式快得多。

接下来,我通过一个实际的例子来说明它的用法。

Git Bisect 的操作步骤

1. 确定大致范围

首先,我们需要确定问题可能出现的范围。假设怀疑问题出现在最近的 100 个 commit,可以用以下命令切换到第 100 个 commit:

git checkout HEAD~100

切换后,测试此版本是否存在问题:

• 如果没有问题,说明 Bug 出现在 HEAD 到 HEAD~100 之间;

• 如果有问题,说明需要扩大搜索范围。

2. 开始使用 Git Bisect

运行以下命令开启 git bisect 模式:

git bisect start
3. 标记有问题的 commit

我们需要指定一个明确有问题的 commit:

git bisect bad <commit_id>

如果当前分支已经是有问题的状态,可以直接执行:

git bisect bad
4. 标记没有问题的 commit

然后,指定一个明确没有问题的 commit:

git bisect good <commit_id>

5. 测试中间的 commit

Git 会自动挑选范围中间的一个 commit,让我们测试并反馈结果。如果测试发现此 commit 没问题,输入:

git bisect good

如果测试发现有问题,输入:

git bisect bad
6. 重复测试直到找到问题

重复上述测试步骤,Git 会逐步缩小范围,最终定位到引入问题的 commit。

虽然理论上我们可以手动实现二分查找,但使用 git bisect 可以显著减少操作复杂度,让调试更加高效。

希望这篇文章能对你有所帮助,下次遇到类似问题时,记得试试这个工具。谢谢阅读!