当代码出现问题,却不知道是哪一次出现了问题,可以使用git bisect
命令,来查找哪一次代码提交引入了错误。
通过这个Github代码库的示例,可以动手试一下这个命令的使用过程。
原理
git bisect
命令的原理是“二分法”,即,找一个提交历史点和当前提交版本进行比较,该命令会取比较的两个提交点中间版本,看看该版本是好的还是坏的,如果是坏的,说明再前半段就出现了问题;如果是好的,说明在后半段出现问题;不断进行二分查找,确定出现问题的那次提交。
示例
将代码clone到本地开始练习:
$ git clone git@github.com:bradleyboy/bisectercise.git
Cloning into 'bisectercise'...
remote: Enumerating objects: 304, done.
remote: Counting objects: 100% (304/304), done.
remote: Compressing objects: 100% (206/206), done.
remote: Total 304 (delta 97), reused 304 (delta 97), pack-reused 0
Receiving objects: 100% (304/304), 29.88 KiB | 527.00 KiB/s, done.
Resolving deltas: 100% (97/97), done.
$ cd bisectercise/
打开目录中的index.html
,这是一个计数器,点击+
号按钮,可以看到计数器没有递增,反而递减,这说明代码有问题。
接下来查找是哪一次出现了问题。首先,检查一下代码提交历史。
$ git log --pretty=oneline
483ed94b63fe3dd4acd10073e0be30a8af36ac2c (HEAD -> master, origin/master, origin/HEAD) readme
7808b0941eab1e47dbafb123704ac7e289a59143 commit 100
4551242eb13dc392d21338128c775fa3557d0d4e commit 99
37b86f1b64ad8cdb609d3720483603cfd474d65e commit 98
...
4d83cfcbaef648345571d77db867b6f9e4146ba7 commit 1
可以看到,这个库一共有101次提交。最早的第一次提交的哈希是4d83cf。
使用git bisect start
命令启动查错,它的格式如下。
$ git bisect start [终点] [起点]
这里从最新一次提交为终点,最早一次提交为起点,如下:
$ git bisect start HEAD 4d83cf
Bisecting: 49 revisions left to test after this (roughly 6 steps)
[b5a131d5eed449db864a36ccc4c367ab28b402ff] commit 51
这样当前位于第51次提交,浏览器刷新测试,发现为正常版本,说明第51次提交是好的,问题出现在第51~100次提交之间,使用git bisect good
标记这次是好的,让git从后半段开始查找问题:
$ git bisect good
Bisecting: 24 revisions left to test after this (roughly 5 steps)
[cd592ce62d90de8bfd7df8ae47648aaee3bf9cc0] commit 76
这次位于第76次提交,发现代码是坏的,使用git bisect bad
标记一下,说明出现问题的代码在51~76之间,不断重复git bisect good
和git bisect bad
标记,直到找到问题。完整调试如下:
$ git bisect start HEAD 4d83cf
Bisecting: 49 revisions left to test after this (roughly 6 steps)
[b5a131d5eed449db864a36ccc4c367ab28b402ff] commit 51
michael@4spaces.org MINGW64 /f/bisectercise ((b5a131d...)|BISECTING)
$ git bisect good
Bisecting: 24 revisions left to test after this (roughly 5 steps)
[cd592ce62d90de8bfd7df8ae47648aaee3bf9cc0] commit 76
michael@4spaces.org MINGW64 /f/bisectercise ((cd592ce...)|BISECTING)
$ git bisect bad
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[4437723ed1ac9a1022311ebb78d3688848a4c9b0] commit 63
michael@4spaces.org MINGW64 /f/bisectercise ((4437723...)|BISECTING)
$ git bisect good
Bisecting: 6 revisions left to test after this (roughly 3 steps)
[54d2dc29e0f23d08c42a2ef16cf20f1145cbe076] commit 69
michael@4spaces.org MINGW64 /f/bisectercise ((54d2dc2...)|BISECTING)
$ git bisect bad
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[68f066184e9c835a0270b904805c608c0b29aa6b] commit 66
michael@4spaces.org MINGW64 /f/bisectercise ((68f0661...)|BISECTING)
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 1 step)
[21306f0075a6fcd255f0d6cefa9f1cf0e1c8eddd] commit 65
michael@4spaces.org MINGW64 /f/bisectercise ((21306f0...)|BISECTING)
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[b47892adec22ee3b0330aff37cbc5e695dfb99d6] commit 64
michael@4spaces.org MINGW64 /f/bisectercise ((b47892a...)|BISECTING)
$ git bisect bad
b47892adec22ee3b0330aff37cbc5e695dfb99d6 is the first bad commit
commit b47892adec22ee3b0330aff37cbc5e695dfb99d6
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:41:36 2018 -0500
commit 64
:100644 100644 b10625ed4a08e037bd78fa82f8642f86425e794f 43a01abbda2fb4df745fac338636a9d78dab769e M index.html
最后发现b47892adec22ee3b0330aff37cbc5e695dfb99d6 is the first bad commit
,即找到了出现问题的那次提交。
使用git bisect reset
退出差错。接下来对代码进行修复就可以了。