git bisect, by example

git bisect can turn out to be very useful when you want to find a bug in a series of commits. It uses binary search to search through commits  and helps you find out where a bug was introduced. Lets take a look at an example.

Say you have a file called controller.py, and you have a ton of developers touching this file. Say this is how the file looks like right now:

#dev1

my_good_code

#dev2

my_good_code

#dev3

my_good_code

#dev4

my_good_code

#dev5

my_good_code

Lets say 5 developers have committed their changes and it works perfect and your git log looks like this. 5 commits (with messages appropriately named ‘first’ to ‘fifth’)

> git log
commit f120025526671c5d84d4529f1c550494b9030434
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:18:22 2017 -0800

 fifth commit

commit 5db3df9c4b126de93924ff93607cac1ded209d7a
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:17:28 2017 -0800

 fourth commit

commit a9a302e438aa8d81c311e2b6f11b6e3e0a723e52
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:16:59 2017 -0800

 third commit

commit 418144048a400616b9956ddffe327d06f7325154
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:16:27 2017 -0800

 second commit

commit a8b6640df07190b394dbbb70f83ac92bf638a30f
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:15:55 2017 -0800

 first commit
>

Now lets say this guy tampers with controller.py

office-space-lumbergh

and well, what do you expect. Your file looks like this now

#dev1

my_good_code

#dev2

my_good_code

#dev3

my_good_code

#dev4

my_good_code

#dev5

my_good_code

#the_tps_guy

my_bad_code

And till the bug is noticed,  everything added from now on has the bug and given this, the seventh commit gives you this file.

#dev1

my_good_code

#dev2

my_good_code

#dev3

my_good_code

#dev4

my_good_code

#dev5

my_good_code

#the_tps_guy

my_bad_code

#dev6

my_good_code_with_a_bad_old_commit

Now lets use git bisect to figure out which commit introduced the bug (we know the sixth commit did). This would be typical workflow of figuring that out.

Do a git log to see what your history looks like


> git log
commit f52415c9da1e8de80c22c4820dac6b762b77e8cc
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 20:09:03 2017 -0800

seventh commit

commit 8831e79d3f211c315e18f9e49ddc05ed615ad2f1
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:57:07 2017 -0800

sixth commit

commit f120025526671c5d84d4529f1c550494b9030434
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:18:22 2017 -0800

fifth commit

commit 5db3df9c4b126de93924ff93607cac1ded209d7a
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:17:28 2017 -0800

fourth commit

commit a9a302e438aa8d81c311e2b6f11b6e3e0a723e52
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:16:59 2017 -0800

third commit

commit 418144048a400616b9956ddffe327d06f7325154
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:16:27 2017 -0800

second commit

commit a8b6640df07190b394dbbb70f83ac92bf638a30f
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:15:55 2017 -0800

first commit
>

You know that the ‘first commit’

a8b6640df07190b394dbbb70f83ac92bf638a30f

works and the ‘seventh commit’

f52415c9da1e8de80c22c4820dac6b762b77e8cc

fails. Enough is enough, lets start bisecting.

> git bisect start
> git bisect good a8b6640df07190b394dbbb70f83ac92bf638a30f
> git bisect bad f52415c9da1e8de80c22c4820dac6b762b77e8cc
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[5db3df9c4b126de93924ff93607cac1ded209d7a] fourth commit

You start bisecting by telling git the start and end points, the good and the bad. Once you do that,  git moves the HEAD to a commit in the middle (binary search) so that you can take a look at your code and spot the bug.

> git log --graph --oneline --decorate --all
* f52415c (master, refs/bisect/bad) seventh commit
* 8831e79 sixth commit
* f120025 fifth commit
* 5db3df9 (HEAD) fourth commit
* a9a302e third commit
* 4181440 second commit
* a8b6640 (refs/bisect/good-a8b6640df07190b394dbbb70f83ac92bf638a30f) first commit
>

At this stage when you view controller.py, this is what you see

#dev1

my_good_code

#dev2

my_good_code

#dev3

my_good_code

#dev4

my_good_code

clearly, it looks good, so lets go ahead and tell git bisect, that this looks good. You do that by, well

> git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[8831e79d3f211c315e18f9e49ddc05ed615ad2f1] sixth commit
> git log --graph --oneline --decorate --all
* f52415c (master, refs/bisect/bad) seventh commit
* 8831e79 (HEAD) sixth commit
* f120025 fifth commit
* 5db3df9 (refs/bisect/good-5db3df9c4b126de93924ff93607cac1ded209d7a) fourth commit
* a9a302e third commit
* 4181440 second commit
* a8b6640 (refs/bisect/good-a8b6640df07190b394dbbb70f83ac92bf638a30f) first commit
>

As you can see, its moved the HEAD to the sixth commit. At this stage, your controller.py looks like this

#dev1

my_good_code

#dev2

my_good_code

#dev3

my_good_code

#dev4

my_good_code

#dev5

my_good_code

#the_tps_guy

my_bad_code

There you go ! The first occurrence of the bug. REPORT IT

> git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[f120025526671c5d84d4529f1c550494b9030434] fifth commit
> git log --graph --oneline --decorate --all
* f52415c (master) seventh commit
* 8831e79 (refs/bisect/bad) sixth commit
* f120025 (HEAD) fifth commit
* 5db3df9 (refs/bisect/good-5db3df9c4b126de93924ff93607cac1ded209d7a) fourth commit
* a9a302e third commit
* 4181440 second commit
* a8b6640 (refs/bisect/good-a8b6640df07190b394dbbb70f83ac92bf638a30f) first commit
>

At this stage, git bisect moves on and moves the HEAD to fifth commit. At this stage controller.py looks like this

#dev1

my_good_code

#dev2

my_good_code

#dev3

my_good_code

#dev4

my_good_code

#dev5

my_good_code

Which looks good, so tell git bisect that it looks good

> git bisect good
8831e79d3f211c315e18f9e49ddc05ed615ad2f1 is the first bad commit
commit 8831e79d3f211c315e18f9e49ddc05ed615ad2f1
Author: Sharath Ravindran <sravindran@SRavindran-MBP.local>
Date: Sun Feb 19 19:57:07 2017 -0800

sixth commit

:100644 100644 54a7baa9c061654e20d5d8cfa9eb5013ca7c02b5 f3cf8836f7fd5b122cf09f206f7ef4171ec0ad29 M controller.py
>

And there you go, the sixth commit ! Go ahead, revert the commit, and move on !

Advertisements
Posted in git.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s