git bisect
是一个很有用的命令,用来查找哪一次代码提交引入了错误。
它的原理很简单,就是将代码提交的历史,按照两分法不断缩小定位。所谓"两分法",就是将代码历史一分为二,确定问题出在前半部分,还是后半部分,不断执行这个过程,直到范围缩小到某一次代码提交。
本文通过一个实例,解释如何使用这个命令。下面是一个代码库,请将它克隆到本地。
$ git clone [email protected]: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
现在就可以开始修复错误了。
(完)
卜叔 说:
真的挺简洁明了啊,谢谢阮老师。
不知道有全分支进行判断吗?
新feature都是在新分支开发,并入dev分支的,再并进主分支,发布。这种情况下也可以找得到吗?
2018年12月24日 13:49 | # | 引用
fwin3000 说:
应该只能在一个分支,我想你的情况在 dev 或者主分支执行都行。因为即使走 GitHub flow,新分支合完就删掉了,dev 或者主分支至少还有那个 merge request 的提交
2018年12月24日 16:05 | # | 引用
junming 说:
期待阮老师写下git rebase, git alias的用法,哈哈
2018年12月24日 17:46 | # | 引用
笨笨熊 说:
拼写错误,是查错的范围,不是 差错
2018年12月24日 22:42 | # | 引用
JustYY 说:
昨天刚学到了这个命令,今天就又复习了一遍。
git bisect 最强的是可以接入自己的脚本,比如 git bisect run script.. 然后自己的脚本可以跑一个或者几个unit test, 返回0代表正确,返回1代表错误,这样 git 就可以二分来查找第一个 bad version 了。
2018年12月25日 06:48 | # | 引用
Thinker 说:
还没用过这么高级的想法,今天学到了
2018年12月26日 10:23 | # | 引用
hh 说:
没学过git,只听说过,感觉对于我这个还没大雪毕业的来说,还需要几年经验。
2018年12月26日 14:13 | # | 引用
blackist 说:
感谢阮一峰老师的git高级用法
2019年1月 3日 09:17 | # | 引用
Lasy 说:
简单入门很容易的,还是建议你学一下。
2019年1月 9日 12:00 | # | 引用
马超 说:
这个命令是怎么知道我的代码有缺陷的?有那个大哥可以告我一下,谢谢!
2019年2月 1日 10:47 | # | 引用
Tate 说:
用这个例子来讲,就是➕不正常了,就说明代码有缺陷。而不是直接通过这个命令来查错
2019年2月 1日 11:41 | # | 引用
Tate 说:
我一般都是直接 checkout 到某一个节点,然后看代码是否正常
2019年2月 1日 11:43 | # | 引用
dawei 说:
直接git blame不就可以看到全部代码的提交记录了么。。。
2019年3月29日 08:44 | # | 引用
鱼肚 说:
可以有多个分支。
一次Merge Commit 相当于一个二叉路口。git bisect 可以尝试两个 branch 的顶层 commit,来确定问题所在分支。
2019年4月25日 20:18 | # | 引用
milai 说:
2019年10月31日 09:53 | # | 引用
Sean 说:
git 帮你切换代码版本,代码缺陷需要自己去判断
2022年2月10日 10:26 | # | 引用
summer 说:
看了阮老师的文章,今天又是有进步的一天
2022年3月 8日 11:01 | # | 引用
linjiejun 说:
2分法查找,代码有没缺陷,由你判断,向git输入`git bisect good`or`git bisect bad`git只是为你缩小范围,找到第一次出现问题的commit
2023年11月15日 16:41 | # | 引用
linjiejun 说:
感觉这玩意,适合小仓库,小项目
2023年11月15日 16:42 | # | 引用
qyl 说:
这个大项目不适合,切到以前的分支,项目就跑不起来了...
2024年11月 1日 09:17 | # | 引用