The git bisect command allows us to performs a binary search to find out what commit causes a bug. It's the fast version of going through each commit from the first one to the last one until you finds out that "Oh, after this commit the bug can be reproduced".

Basically what you do is tell Git where things were working (meaning on what commit you remember the bug didn't appear), and then you tell Git where things are not working (meaning a commit where the bug can be reproduced, that can be the last one).

It's easy with an example

In theory sounds great but it's better if we go through an example to learn how to use the git bisect command.

I have a small fake project with a series of commits and I introduced a bug in one of them. Of course, the commit messages are self explanatory but we need that to see if the git bisect really works.

We are going to find out on what commit a typo was introduced on the content of my example.txt file.

Finding the commits where things works and doesn't

This is the easy part and you probably know how to do it.

Checkout to an old commit, see if the bug disappeared, write down the commit hash, and come back to the HEAD. And you can use the newest commit hash as the bad point.

Here's the list of my commits and the one I choose for the good and bad points.

commit 9cc1e21a4422a3e1365bd04b616ddafd98475c3e  
Improved ways to contact us.  
(here things are bad)

commit 785361159507faa755dfb4a1aaaac8cb7ad18c7e  
Added more text to encourage people.

commit 5603f08930ad4aaf84843f6205f25cdd0f684f4f  
Added a signature.

commit 45493f69eba7153d7d954f0eeb7e4973e32d9f3a  
Added a way to contact us in case he/she finds a typo.

commit 9487c88848e056f120166e0a5844822cb0f6b8a4  
Added even more text to the example.txt file to encourage the user to report any typo.

commit c04e336490796f22423b9685c0ffe745ebcddcbb  
A wild typo appears...

commit 2fec0d56c80fd1f7f000ab31ecba643d4c12533d  
Improved example.txt file by adding more text to it.

commit 979ba26a9e0eaeae35e0e236bc14126708a942a6  
Updated example.txt file with some text without a typo.  
(here things are good)

commit 27c9d5ec2bcae6f1aa8ee295483ac9696e579296  
Initial commit with example.txt empty.  

Indicating the commits where things works and doesn't

You have the good and the bad, let's transfer that knowledge to Git.

git bisect start  
git bisect good 979ba26a9e0eaeae35e0e236bc14126708a942a6  
git bisect bad 9cc1e21a4422a3e1365bd04b616ddafd98475c3e  

Bisecting

Git will move you to any of the commits trap in the middle of the good and bad points. And the only thing you need to do is to tell Git if that commit is a good or a bad one, meaning if you can reproduce the bug or not.

Here's what I get:

➜  Bisect_Project git:(master) git bisect start
➜  Bisect_Project git:(master) git bisect good 979ba26a9e0eaeae35e0e236bc14126708a942a6
➜  Bisect_Project git:(master) git bisect bad 9cc1e21a4422a3e1365bd04b616ddafd98475c3e
Bisecting: 3 revisions left to test after this (roughly 2 steps)  
[9487c88848e056f120166e0a5844822cb0f6b8a4] Added even more text to the example.txt file to encourage the user to report any typo.
➜  Bisect_Project git:(9487c88)

I check the example.txt file to see if the typo is there or not.

This test hat no typo. Please, feel free to check it.

If you find a problem, please report it.  

Is there (it says hat instead of has), so it's a bad commit. I tell Git about it and he move me to anothe commit.

➜  Bisect_Project git:(9487c88) git bisect bad
Bisecting: 0 revisions left to test after this (roughly 1 step)  
[c04e336490796f22423b9685c0ffe745ebcddcbb] A wild typo appears...

I check the example.txt file again.

This test hat no typo. Please, feel free to check it.  

The typo is there, I tell Git about it and he'll move me again.

➜  Bisect_Project git:(c04e336) git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)  
[2fec0d56c80fd1f7f000ab31ecba643d4c12533d] Improved example.txt file by adding more text to it.

I check the example.txt file one more time.

This test has no typo. Please, feel free to check it.  

No typo! It's a good commit.

➜  Bisect_Project git:(2fec0d5) git bisect good
c04e336490796f22423b9685c0ffe745ebcddcbb is the first bad commit  
commit c04e336490796f22423b9685c0ffe745ebcddcbb  
Author: nahuelsanchez <nsanchez@summasolutions.net>  
Date:   Fri Feb 19 22:52:04 2016 -0300

    A wild typo appears...

:100644 100644 5aebed1a496b67a06fe93b31d9590eae6fb258ad 657a182a496be92d26c948ece9cd9fa0061e03bb M    example.txt
➜  Bisect_Project git:(2fec0d5)

And there we have it. Git is telling us on what commit the bug appeared for the first time. It's up to your skills to check the code and fix it.

When you want to return to the HEAD just do a git bisect reset and you'll be back.