在git中,我们有bisect
方便地查找第一个错误提交,如下所示:
git bisect start linux-next/master v2.6.26-rc8
git bisect run make kernel/fork.o
但前提是我知道哪个旧的提交是好的。在本例中,它是v2.6.26-rc8。
如果我不知道哪个提交是好的,会发生什么?
是否可以写一个脚本,在git提交中反向循环,从当前HEAD开始,从最新的到最旧的,并自动测试每个提交,直到第一个好?
git bisect
通过提交历史执行二进制搜索。good
和bad
只是为这个搜索提供了边界。然后Git在这个范围内搜索"坏"的提交。上一条是"good">
重要的是"好"提交是在特性失效之前,以及"坏"之前。提交是在特性失效之后。如果您不确定该特性何时失效,选择在该特性引入之前提交。
如果你不确定,选择一个非常旧的提交。您甚至可以选择第一次提交。这并不像听起来那么荒谬。二分搜索非常有效;1万个提交可以在log2(10000)次尝试或13次尝试中搜索。
例如,假设您的提交历史是这样的:
a - b - c - d - e - f - g - h - i [main]
你知道这个特性现在坏了,你不知道它什么时候是好的,但你知道它是在d点引入的。选择c,在这个特性引入之前的提交,作为"好";提交。
$ git bisect start
$ git bisect bad
$ git bisect good c
HEAD
a - b - c - d - e - f - g - h - i [main]
g b
然后git bisect
将对d - e - f - g - h
进行二进制搜索,直到它在一个好的提交之后立即发现一个坏的提交。
在这种情况下,它将以f开头。假设这是坏的。
$ git bisect bad
HEAD
a - b - c - d - e - f - g - h - i [main]
g b b
Git假设f之后的所有内容都是坏的。那么它可能会尝试d。假设这很好。
$ git bisect good
HEAD
a - b - c - d - e - f - g - h - i [main]
g g b b
然后它会尝试e,假设这是坏的
$ git bisect bad
HEAD
a - b - c - d - e - f - g - h - i [main]
g g b b b
他打破了这个特性。