git bisect 命令教程

作者: 阮一峰

日期: 2018年12月24日

腾讯课堂 NEXT 学院

git bisect是一个很有用的命令,用来查找哪一次代码提交引入了错误。

它的原理很简单,就是将代码提交的历史,按照两分法不断缩小定位。所谓"两分法",就是将代码历史一分为二,确定问题出在前半部分,还是后半部分,不断执行这个过程,直到范围缩小到某一次代码提交。

本文通过一个实例,解释如何使用这个命令。下面是一个代码库,请将它克隆到本地。


$ git clone git@github.com:bradleyboy/bisectercise.git
$ cd bisectercise

这个库是一个网页index.html,在浏览器打开这个网页。


$ open index.html

网页上是一个计数器,有两个按钮。点击+号按钮,可以看到计数器没有递增,反而递减,这说明代码有问题。

现在,就要来查找,到底哪一次代码提交,引入了错误。首先,检查一下代码提交历史。


$ git log --pretty=oneline

可以看到,这个库一共有101次提交。最早的第一次提交的哈希是4d83cf

git bisect start命令启动查错,它的格式如下。


$ git bisect start [终点] [起点]

上面代码中,"终点"是最近的提交,"起点"是更久以前的提交。它们之间的这段历史,就是差错的范围。

这个例子中,我们选择全部的代码历史。起点是第一次提交4d83cf,终点是最近一次的HEAD。当然,指定其他范围也可以。


$ git bisect start HEAD 4d83cf

执行上面的命令以后,代码库就会切换到这段范围正当中的那一次提交,本例是第51次提交。

现在刷新浏览器,点击+按钮,发现可以正常递增。使用git bisect good命令,标识本次提交(第51次)没有问题。


$ git bisect good

既然第51次提交没有问题,就意味着错误是在代码历史的后半段引入的。执行上面的命令,Git 就自动切换到后半段的中点(第76次提交)。

现在刷新浏览器,点击+按钮,发现不能正常递增。使用git bisect bad命令,标识本次提交(第76)有问题。


$ git bisect bad

执行上面的命令以后,Git 就自动切换到第51次到第76次的中点(第63次提交)。

接下来,不断重复这个过程,直到成功找到出问题的那一次提交为止。这时,Git 会给出如下的提示。


b47892 is the first bad commit

既然找到那个有问题的提交,就可以检查代码,确定具体是什么错误。

然后,使用git bisect reset命令,退出查错,回到最近一次的代码提交。


$ git bisect reset

现在就可以开始修复错误了。

(完)

留言(15条)

真的挺简洁明了啊,谢谢阮老师。
不知道有全分支进行判断吗?
新feature都是在新分支开发,并入dev分支的,再并进主分支,发布。这种情况下也可以找得到吗?

引用卜叔的发言:

真的挺简洁明了啊,谢谢阮老师。
不知道有全分支进行判断吗?
新feature都是在新分支开发,并入dev分支的,再并进主分支,发布。这种情况下也可以找得到吗?

应该只能在一个分支,我想你的情况在 dev 或者主分支执行都行。因为即使走 GitHub flow,新分支合完就删掉了,dev 或者主分支至少还有那个 merge request 的提交

期待阮老师写下git rebase, git alias的用法,哈哈

拼写错误,是查错的范围,不是 差错

昨天刚学到了这个命令,今天就又复习了一遍。
git bisect 最强的是可以接入自己的脚本,比如 git bisect run script.. 然后自己的脚本可以跑一个或者几个unit test, 返回0代表正确,返回1代表错误,这样 git 就可以二分来查找第一个 bad version 了。

还没用过这么高级的想法,今天学到了

没学过git,只听说过,感觉对于我这个还没大雪毕业的来说,还需要几年经验。

感谢阮一峰老师的git高级用法

引用hh的发言:

没学过git,只听说过,感觉对于我这个还没大雪毕业的来说,还需要几年经验。

简单入门很容易的,还是建议你学一下。

这个命令是怎么知道我的代码有缺陷的?有那个大哥可以告我一下,谢谢!

引用马超的发言:

这个命令是怎么知道我的代码有缺陷的?有那个大哥可以告我一下,谢谢!

用这个例子来讲,就是➕不正常了,就说明代码有缺陷。而不是直接通过这个命令来查错

我一般都是直接 checkout 到某一个节点,然后看代码是否正常

直接git blame不就可以看到全部代码的提交记录了么。。。

引用卜叔的发言:

真的挺简洁明了啊,谢谢阮老师。
不知道有全分支进行判断吗?
新feature都是在新分支开发,并入dev分支的,再并进主分支,发布。这种情况下也可以找得到吗?

可以有多个分支。

一次Merge Commit 相当于一个二叉路口。git bisect 可以尝试两个 branch 的顶层 commit,来确定问题所在分支。

引用Tate的发言:

用这个例子来讲,就是➕不正常了,就说明代码有缺陷。而不是直接通过这个命令来查错

这个命令就是二分查找,是不是有错误,还是需要你自己判断和标记的。

我要发表看法

«-必填

«-必填,不公开

«-我信任你,不会填写广告链接