点击这里成为作者 · 更新于 2017-10-22 19:00:25

第48关 bisect

A bug was introduced somewhere along the way. You know that running "ruby prog.rb 5" should output 15. You can also run "make test". What are the first 7 chars of the hash of the commit that introduced the bug.

在开发过程中引入了一个 bug。已知运行 "ruby prog.rb 5" 应该输入 15,你也可以运行 "make test" 进行测试。你需要确定引入 bug 的那次提交的哈希值的前7位。

在程序持续迭代的过程中不免会引入 bug,除了定位 bug 的代码片断,我们还想知道 bug 是在什么时间被引入的,这时就可以借助 Git 提供的 bisect 工具来查找是哪次提交引入了 bug。bisect 是用二分法来查找的,就像用二分查找法查找数组元素那样。

运行 make test 可以测试程序是否正确执行,它会先执行 "ruby prog.rb 5" 语句,然后再分析输出结果是否等于15,如果不等于15,就会显示 make: *** [test] Error 1

我们先看一下提交历史,一共20次提交:

$ git log --pretty=oneline
12628f463f4c722695bf0e9d603c9411287885db Another Commit
979576184c5ec9667cf7593cf550c420378e960f Another Commit
028763b396121e035f672ef5af75d2dcb1cc8146 Another Commit
888386c77c957dc52f3113f2483663e3132559d4 Another Commit
bb736ddd9b83d6296d23444a2ab3b0d2fa6dfb81 Another Commit
18ed2ac1522a014412d4303ce7c8db39becab076 Another Commit
5db7a7cb90e745e2c9dbdd84810ccc7d91d92e72 Another Commit
7c03a99ba384572c216769f0273b5baf3ba83694 Another Commit
9f54462abbb991b167532929b34118113aa6c52e Another Commit
5d1eb75377072c5c6e5a1b0ac4159181ecc4edff Another Commit
fdbfc0d403e5ac0b2659cbfa2cbb061fcca0dc2a Another Commit
a530e7ed25173d0800cfe33cc8915e5929209b8e Another Commit
ccddb96f824a0e929f5fecf55c0f4479552246f3 Another Commit
2e1735d5bef6db0f3e325051a179af280f05573a Another Commit
ffb097e3edfa828afa565eeceee6b506b3f2a131 Another Commit
e060c0d789288fda946f91254672295230b2de9d Another Commit
49774ea84ae3723cc4fac75521435cc04d56b657 Another Commit
8c992afff5e16c97f4ef82d58671a3403d734086 Another Commit
80a9b3d94237f982b6c9052e6d56b930f18a4ef5 Another Commit
f608824888b83bbedc1f658be7496ffea467a8fb First commit

首先启动 bisect 查找流程:

$ git bisect start
$ git bisect good f608824888b
$ git bisect bad 12628f463f4
Bisecting: 9 revisions left to test after this (roughly 3 steps)
[fdbfc0d403e5ac0b2659cbfa2cbb061fcca0dc2a] Another Commit

第2行和第3行是定义 bisect 的查找范围,git bisect goodgit bisect bad 表示当前程序通过或没有通过测试,在第2行后面以第一次提交的哈希值为参数,在第3行后面以最后一次提交的哈希值为参数,说明查找范围是全部20次提交。接着 Git 定位了位于中间那个提交,它的哈希值是 "fdbfc0d403e5a",并计算出剩余的提交还有9次,大约还需要3次二分查找。

这时,我们对程序进行测试,测试通过,所以我们反馈 good

$ make test
ruby prog.rb 5 | ruby test.rb
$ git bisect good
Bisecting: 4 revisions left to test after this (roughly 2 steps)
[18ed2ac1522a014412d4303ce7c8db39becab076] Another Commit

Git 继续进行二分查找,这次定位的哈希值是 "18ed2ac1522a01",我们再对程序测试,测试没有通过,所以我们反馈 bad

$ make test
ruby prog.rb 5 | ruby test.rb
make: *** [test] Error 1
$ git bisect bad
Bisecting: 2 revisions left to test after this (roughly 1 step)
[9f54462abbb991b167532929b34118113aa6c52e] Another Commit

就这样,经过几轮测试,当 Git 给出下面的消息时,表示找到了:

18ed2ac1522a014412d4303ce7c8db39becab076 is the first bad commit

下面是对查找过程的回顾:

12628f463f4c72 Another Commit
979576184c5ec9 Another Commit
028763b396121e Another Commit
888386c77c957d Another Commit
bb736ddd9b83d6 Another Commit
18ed2ac1522a01 Another Commit 第2次 bad
5db7a7cb90e745 Another Commit 第4次 good
7c03a99ba38457 Another Commit
9f54462abbb991 Another Commit 第3次 good
5d1eb75377072c Another Commit
fdbfc0d403e5ac Another Commit 第1次 good
a530e7ed25173d Another Commit
ccddb96f824a0e Another Commit
2e1735d5bef6db Another Commit
ffb097e3edfa82 Another Commit
e060c0d789288f Another Commit
49774ea84ae372 Another Commit
8c992afff5e16c Another Commit
80a9b3d94237f9 Another Commit
f608824888b83b First commit

第48关过关画面如下:

第48关 bisect

上一篇: 第47关 reorder 下一篇: 第49关 stage lin...