Git 的二分查找功能(git bisect)可以帮助你快速定位引入问题的提交。通过二分查找,你可以高效地缩小范围,找到导致问题的提交。

41.1 二分查找(git bisect)

git bisect 允许你通过二分查找的方式,找到引入问题的提交。

开始二分查找会话

你需要提供两个提交引用:一个没有问题的“好”提交和一个存在问题的“坏”提交。通常,“坏”提交是当前 HEAD。

# 开始二分查找会话
$ git bisect start

# 提供一个没有问题的提交
$ git bisect good 49c747d

# 提供一个存在问题的提交
$ git bisect bad HEAD

Git 会开始二分查找:它将提交范围分成两半,并切换到中间的提交。检查代码以确定该提交是“好”还是“坏”:

# 如果该提交没有问题,告诉 Git 它是“好”的
$ git bisect good

# 如果该提交存在问题,告诉 Git 它是“坏”的
$ git bisect bad

Git 会根据你的指令继续在剩余的“坏”提交子集中进行二分查找。除非你的标记有误,否则 Git 最终会定位到引入问题的提交。

完成查找后,记得运行以下命令结束二分查找会话并返回到 HEAD:

$ git bisect reset

如果你有一个可以检查问题的脚本,可以使用以下命令自动化这个过程:

$ git bisect run [script] [arguments]

其中 [script] 是脚本的路径,[arguments] 是传递给脚本的参数。运行此命令后,Git 会自动执行二分查找,在每一步根据脚本的退出代码执行 git bisect good 或 git bisect bad。脚本退出码为 0 表示“好”,退出码为 1-124、126 或 127 表示“坏”。125 表示脚本无法测试该提交(这将触发 git bisect skip)。

41.2 半自动查找问题提交

假设你在 master 分支上,发现某些功能不再正常工作(引入了回归),但你不知道具体是哪个提交导致的。你只知道在上一个发布版本(比如标记为 old-rel 或已知的提交哈希)时一切正常。

Git 可以通过二分查找帮助你快速定位引入回归的提交。

首先,开始二分查找:

git bisect start master old-rel

这会告诉 Git,master 是第一个已知的“坏”版本,old-rel 是最后一个已知的“好”版本。Git 会切换到这两个提交中间的一个提交(此时处于分离 HEAD 状态)。现在你可以进行测试。根据测试结果,运行以下命令:

git bisect good
# 或
git bisect bad

如果某个提交无法测试,你可以轻松地使用 git reset 并重新测试,Git 会自动处理这种情况。

经过几步后,Git 会输出引入问题的提交哈希。

如果需要中断二分查找,运行以下命令:

git bisect reset

Git 会恢复到之前的 HEAD 状态。