Recently at work, I encountered a couple of complex bugs with unclear origins,
making it difficult to pinpoint exactly when they first appeared. In general
as codebases grow larger and more complex, tracking down the source of bugs can
become increasingly challenging. Fortunately, Git provides a powerful tool called
git bisect
that can help pinpoint the exact commit that introduced a bug.
In this post, we’ll see how to use git bisect effectively to save a lot of time and streamline your debugging process.
What is Git Bisect?
Git bisect is a binary search tool that helps you find the commit that introduced a bug in your project. By marking known “good” and “bad” commits, git bisect can automatically checkout commits between those points, allowing you to test each one until you locate the problematic change.
Example use
Let’s consider a scenario where we travel back in time and our website used to look like this:
Our good state
And let’s assume that this state was back in some random commit with hash e4824da
.
All hell broke loose
Some time passes by, more commits are coming in and everything is working. However after a while we notice that the site looks like this…
We notice that there are two new bugs appearing compared to the old version:
We are puzzled by how long these issues had persisted and which specific commit might
have introduced them. Its time to use git bisect
Let’s try and resolve the first issue regarding the missing styles, we will need to know the
commits for our good and bad states. So we git log
to find the hash of our commits/states.
We will mark d138661
(master) as “bad” commit/state as we’ve confirmed that our site is broken while on it.
Likewise we will mark e4824da
as “good” because we’re certain that when we are on that commit everything is fine.
Now we see that Git has automatically checked out a commit right in the middle of our two states.
We check if our site’s styles are applied but it seems that the issue persisted so we mark the commit as bad
We check again but no luck…So we mark this commit as bad as well and we continue
We check our site and our styles are back!! We mark this commit as “good” and
by that git bisect
gives us the first “bad” commit.
Now we found our faulty commit and finish the process with:
But let’s investigate the faulty commit.
We can see that we accidentally messed up the link reference 🤦. Now that we found the culprit lets remove it.
Let’s check now our site again while on master
branch:
Nice! We got our styles back. However our title is still wrong…
Automating git bisect
Let’s try now to find the faulty commit again but this time make git do the check for us based on a “condition” we give it.
But now I want to provide Git a custom test case I wrote for this specific bug which I want it to check everytime bisect a new commit.
Let’s use Git to automatically test each commit and mark them as “bad” or “good” based on whether the test case passes or fails.
As demonstrated above, git bisect run
executed the command we provided, multiple times across different commits in the repository’s history.
This automated process efficiently identified the first commit where our test succeeded, indicating that the commit immediately preceding it
was the first “bad” commit that introduced the issue.
Now we can remove this faulty commit the same way we did before:
Finally let’s again our site again:
Nice! We not only tackled the actual bug but also automated the process, minimizing both our effort and the potential for any human error.
Conclusion
Git bisect is a really useful tool for efficiently tracking down bugs in large codebases.
Although in these trivial examples above it could not be that obvious straight away. By leveraging its binary
search algorithm, we can save time and frustration when debugging. Whether used manually
or with automation, git bisect
could be a very usefull toolkit especially when you need to indentify which commit
to revert fast.
Remember, the key to effective debugging is not just finding the bug, but understanding why it occurred.
Once we’ve identified the problematic commit with git bisect
and resolve the issue, we can take the time to analyze the changes and
prevent similar issues in the future.