# Finding a bug when you have no idea where to start

## TL;DR
1. Start a session
```
git bisect start
``` 
2. Set the bad commit

    Either the **current commit** you're checked out has the bug
```
git bisect bad
``` 
or a **specific commit** has the bug, for example, `dcf12e8`
```
git bisect bad dcf12e8
```
3. Set the good commit (e.g. `eff13d3` **doesn't have** the bug )
```
git bisect good eff13d3
``` 
4. Run and test the application yourself (you have to tell Git if the bug is there or not)

    Either the bug is present, then run
```
git bisect bad
```
or the bug is not present, then run
```
git bisect good
```
5. Repeat step 4 until the **first** bad commit is found


**Note:** you can use tags instead of commit hashes as well.


## When is it useful?
I usually find it quite useful when the two following conditions are met:
- The bug was not present in the latest release but it's present in the current release candidate
- I have no idea what is causing the bug (therefore I don't know where to look)

Imagine the following scenario. A new release (let's say 2.80) is about to be released and QA is doing regression. You're enjoying a deserved coffee after a job well done when, unexpectedly, you're tagged on Slack...you know that it's not a good signal...

![D'oh!](https://media.giphy.com/media/32mC2kXYWCsg0/giphy.gif)

So, you've just been informed that a blocker was found during regression and it has to be fixed. At this point, several thoughts go through your mind:

*"Okay, hopefully, it's not my code that is breaking the app so I'm safe"* (AKA throw one of your colleagues under the bus)

*"Let's look at the ticket, it will surely be something easy to fix. D'oh! It isn't!"*

Okay, you have no choice but to fix it. You read the ticket and the bug is odd. You don't have a clue why it's failing and what is causing it.

**The only thing you know for sure is that 2.80 has the bug but 2.79 doesn't.** Then, `git bisect` is your friend in this scenario.

## How it works under the hood
Git Bisect relies on the binary search algorithm to find the **first bad commit** (the commit that introduced the bug). So, let's start by starting the session:

`git bisect start`

Then, we have to let Git know which commit has the bug for sure and which one doesn't. We know that `2.80` has the bug and that `2.79` doesn't, so:

`git bisect bad 2.80` (or `git bisect bad` if the current commit has the bug)

`git bisect good 2.79`

At this point, our setup is something like this:

![Untitled Diagram.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623132713399/F9h5aZT0v.png)

Then Git **automatically** checks out a commit in the middle and **we have to run the application to check if the bug is present or not**:
![D'oh!](https://cdn.hashnode.com/res/hashnode/image/upload/v1623132440589/DZNumo2TC.png)

Let's say that the bug is present in **C3** (`dcf12e8`), then we know that the second half has the bug for sure, therefore, the bug was introduced somewhere in the first half. We have to let Git know that **C3** has the bug:

`git bisect bad dcf12e8`

Now Git automatically checks out a new commit:

![Untitled Diagram-Page-2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623133570700/lhphqFb_1.png)

Let's say now that the bug is not present in **C1** (`eff13d3`), then we have to let Git know about this:

`git bisect good eff13d3`

So the first half is bug-free, therefore, it is discarded. Only the **C2** commit is left and Git checks it out, we run the app and let's say that the bug is present. Bingo! The first bad commit has just been found (because **C1** is bug-free):

![Untitled Diagram-Page-3.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1623133815657/AqKim5Au0.png)

Finally, Git will provide you with the hash (author, date, etc.) of the first bad commit.

## Final thoughts
`git bisect` is not the Holy Grail, sometimes even if you find the commit that introduced the bug, it's simply not enough to figure out what the problem is.

But, even so, it's a skill that can help you to discard possible scenarios and fence the problem.

## Documentation
https://git-scm.com/docs/git-bisect  
https://www.git-tower.com/learn/git/faq/git-bisect/

## Images used
https://unsplash.com/photos/IClZBVw5W5A

