git bisect
is a very powerful command for finding out which commit is a bad commit when bug occurs.
The rationale behind this command is that it pin locates the bad commit by divide and conquer. It divides the commit history into two equal parts, then determines whether the bad commit is at the first half or at the other half. This process will continue until the bad commit is located.
Here is a really good example created by bradleyboy, this is a simple git repository which demonstrates a bad commit in the index.html. First, please clone the repository into local.
$ git clone git@github.com:bradleyboy/bisectercise.git
$ cd bisectercise
It contains a webpage which will show below when opened in browser.
Basically it is a counter which will increment by one when click + and will decrement by one when click -. If the number doesn't increase when click +, it means there is a bug in the code. Now let's use git bisect
command to find the bad commit.
First check the log of git commit.
git log --pretty=oneline
There are 101 commits in total and the first commit is
4d83cfcbaef648345571d77db867b6f9e4146ba7
Now use git bisect to check the bad commit. The syntax of the command is:
git bisect start [end_commit] [begin_commit]
end_commit will be the later commit and begin_commit will be the earlier commit.
In this example, we will start with the very first commit and end with the latest commit. So the command would be:
git bisect start HEAD 4d83cf
When this command is executed, the repository will be checked out to commit 51.
D:\Project\Playground\GitBisect\bisectercise>git bisect start HEAD 4d83cf
Bisecting: 49 revisions left to test after this (roughly 6 steps)
[b5a131d5eed449db864a36ccc4c367ab28b402ff] commit 51
D:\Project\Playground\GitBisect\bisectercise>git log
commit b5a131d5eed449db864a36ccc4c367ab28b402ff (HEAD)
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:40:07 2018 -0500
commit 51
commit 6ac79e6285f46aa93bc1d7b75b8d3e5e733f0e38
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:40:07 2018 -0500
commit 50
commit cbfaa8504e6fb14d01b0668ab3ef03dd4677fbb4
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:40:07 2018 -0500
commit 49
Now refresh the browser and the + button works properly. Mark this commit as good.
git bisect good
The commit will be switched to commit 76 as commit 51 has no problem and the problem must be in a later commit.
D:\Project\Playground\GitBisect\bisectercise>git bisect good
Bisecting: 24 revisions left to test after this (roughly 5 steps)
[cd592ce62d90de8bfd7df8ae47648aaee3bf9cc0] commit 76
D:\Project\Playground\GitBisect\bisectercise>git log
commit cd592ce62d90de8bfd7df8ae47648aaee3bf9cc0 (HEAD)
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:41:53 2018 -0500
commit 76
commit dd6b85e2604c0b2db5218ed080596cfca485e242
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:41:53 2018 -0500
commit 75
commit 6580e5074ad69418a417b72f5d3b8bbf2120c6a7
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:41:53 2018 -0500
commit 74
Refresh the browser again and now + button doesn't work properly anymore. This indicates the bad commit is between commit 51 and commit 76. Now mark the commit as bad.
git bisect bad
The commit now will be switched to commit 63.
D:\Project\Playground\GitBisect\bisectercise>git log
commit 4437723ed1ac9a1022311ebb78d3688848a4c9b0 (HEAD)
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:40:07 2018 -0500
commit 63
commit 050059f41862f228871666e928f66663279ff915
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:40:07 2018 -0500
commit 62
commit a4c2943a7ac2f2b8b70a5086afc6ed1a56b90298
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:40:07 2018 -0500
commit 61
Continue above process until the first bad commit is found. It will show something like below.
D:\Project\Playground\GitBisect\bisectercise>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
Now the bad commit is found. And we can find what's going wrong with the commit. Then reset to latest commit and fix the issue.
git bisect reset
Go and fix the issue.
enc_commit should read end_commit