Understanding git bisect!
Published: 2024-07-04 19:52:52

Have you ever been put in a situation where a bug has been spotted on your project, which you know was not there some time ago but you do not know when it was introduced. 

This situation forces you into, at least, 2 possible paths 👇🏻

- Trying to debug your codebase to find out where the bug is coming from, which in large codebases or certain situations can become difficult.
- Going back to previous commits one by one, which in big projects or those shared by lots of people may imply going back tons of commits, which can become really time consuming to say the least.

If this seems like the situation you’re facing or have ever faced, keep reading!

Imagine you’re facing the following case 👇🏻

![Example Image 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g4o5jkybx5ohgitfyg6n.png)

If you needed to spot where the issue was introduced at, you would start a linear search where you would go back 1 commit by 1 commit and seeing where the issue was introduced

![Example Image 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x7wurxi77nmxx2k660ui.png)

Imagine the issue was introduced 40 commits ago, you would have been forced to checkout 40 times until you found the first commit where the bug did not exist 😱

**What does `git bisect` offer?**

The idea behind **`git bisect`** is to replace the linear search by [a binary search](https://www.geeksforgeeks.org/binary-search/). Let’s look at it through an example (for the sake of simplicity, the example will be reduced to a use case with 8 commits) 👇🏻

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9saxs2a2i9nm1wn5w3u.png)

When running `git bisect`  we will be asked to give a commit in which the issue was not happening (start commit) and a commit where the issue has been spotted (end commit):

- Start commit → _Commit 1_ (just try some random older commits and take the first one that works)
- End commit → _Commit 8_

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/viz61ax4ogsu6ht6jiz1.png)

Binary search will take a random commit in the middle called pivot, Commit 5 for example, and check if the issue still appeared there or not.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ecsaluosl0n1j3o3mca.png)

On our case, _Commit 5_ still presents the issue so we can ensure that _Commit 6 & Commit 7 & Commit 8_ won’t be the ones that introduced it. 

Just like this, we have avoided checking _Commit 6 & Commit 7_. Way to go!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09ohx6wpuen849vw1jar.png)

We will just take a pivot around the middle again, on this case _Commit 2_. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzs6mh762flbpzvpfia0.png)

In this case, _Commit 2_ does not present the issue! Therefore, we can ensure that _Commit 1_ did not introduce it neither. Another commit less to check again!

 We just need to check if the bug was introduced by *Commit 3* or *Commit 4* 🏃🏻

We’ll repeat the process!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbi8cq5eu4pfupyg6rb7.png)

Same as before is done and therefore we’ll easily find out that *Commit 3* introduced our bug, and now we just need to look through the changes done in that specific commit, easy! 🥳

**You might be wondering…**

Okay the drawings look good but, is this really faster? 

In general terms, the costs usually are something like 👇🏻

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ua6wvxf8zbn8rncwjdva.png)

**That’s it!**

I hope you found this post useful and that it might help you next time you’re facing something similar!