Mastering git bisect to streamline debugging process
We know how frustrating it can be when you’re working on a software project and you encounter a bug, especially when these bugs are tricky to track down.
Git has a tool called git bisect that can help you find the specific commit that introduced a bug. In this article, we’ll go over what git bisect is, how it works, and we’ll even provide an example workflow to help you master it.
What is git bisect?
Finding elusive bugs in your commit history can be sometimes daunting. But the good news is that Git Bisect is here to help with that!
All you have to do is mark a known good commit (the one where the bug isn’t present) and a known bad commit (where the bug is), and Git Bisect will take you on a guided path through a series of commits history, and helping you narrow down the process until you find the filthy commit.
This approach is a life saver compared to checking each commit manually.
How git bisect Works
The process of using git bisect is simple, and can be broken down into the following steps:
Start Bisect:
Initialize bisect and mark the current commit or any other commit bad.
Bisect:
When you use git bisect, Git uses a binary search approach to help you find the commit where a bug or issue was introduced, which is way more efficient and fast than testing commits one by one.
Once you mark one commit as good (bug free) and another one as bad (contains the bug) and supposing you have a sequence of commits like this:
A - B - C - D - E
A is the good commit and E is the bad one.
So git divides the range of commits between the good and bad into two halves and checks out the commit in the middle so in the sequence above, Git will check out C, the middle commit.
And after checking out the middle commit, you test whether the issue is present in C:
If the bug is present, mark C as bad:
git bisect bad
This eliminates the first half (A and B) from the search.
If the bug is not present, mark C as good:
git bisect good
This eliminates the second half (D and E) from the search.
Git continues this process, halving the range each time and checking out the middle commit, until it reaches the exact commit that introduced the bug.
But hold on! Why exactly the Middle Commit?
When the middle commit is being checked, it helps you find the bad one a lot faster. It’s the binary search, which is like a super-speed search. So, you won’t have to spend as much time testing commits one by one.
For example, if there are 16 commits, binary search only takes at most 4 tests to find the bug. But, if we tested sequentially, it could take up to 16 tests.
Test: Test the intermediate commit: At this stage, you will need to manually test whether the bug exists in the current commit that Git has checked out.
- This can mean checking out previous commits one by one and running the application and verifying whether the bug is present.
- If you are testing a web application, you might open the app in a browser and check for the issue.
- If you’re running tests, you can use your test suite (e.g. PHPUnit, etc.) to check whether everything passes or fails in this commit.
Repeat the process:
Based on your test results, Git narrows down the range and checks out the next middle commit.
Identify:
Continue the process until the exact commit that introduced the bug is detected.
Basic Workflow for Using git bisect:
Start the Bisecting Process: First, navigate to your repository, and start by marking the “bad” commit (where the bug appears) and the “good” commit (where the bug is not present).
git bisect start #Start git bisectgit bisect bad #Mark current commit as bad (where the bug is present)git bisect good <commit_hash> #Mark a known good commit
You can get the <commit_ID> of a good commit by using:
git log
P.S : In order to get the good commits references, you can keep checking out the previous commits one by one by running:
Git checkout HEAD~1
Test the Intermediate Commits:
Git will now split the range into two halves and check out a commit in the middle of the good and bad commits. You need to test whether the bug exists at this commit.
After testing, mark it as good or bad:
git bisect good #If the bug is not present in this commitgit bisect bad #If the bug is present in this commit
Repeat Until You Find the Commit:
Git will continue narrowing the range by checking out a new commit in the middle of the current range after each mark. Keep marking the commits as good or bad, and eventually, Git will point you to the problematic commit.
Finish the Bisecting Process:
Once Git finds the offending commit, you can stop the bisect process with:
git bisect reset
Example Use Case
Let’s say you have a bug in your app, but you’re unsure which commit introduced it. You know that the app was working fine a couple of days ago, but it’s broken now.
To track down the annoying bug, let’s see who we can achieve this by following the below example:
Start bisect process by running:
git bisect start
Suppose the current commit (HEAD) is where the bug first appears
git bisect bad
This is a commit where the bug didn’t exist
git bisect good <commit_ID>
P.S : you can get commit ID by running:
git log
or
git reflog
Git will automatically split the range history into tow halves, one for bad and one for good commits and then checks out a commit in the middle of that range.
Test and mark the commit as good or bad accordingly
git bisect good
or
git bisect bad
Repeat until Git finds the exact commit where the bug was introduced.
Advanced git bisect Features
Skipping Commits:
If you come across a commit that you cannot test for some reason (e.g., the commit doesn’t compile), you can tell Git to “skip” it:
git bisect skip
This will allow Git to ignore that commit and continue the search.
Visualizing Bisecting:
If you want to visualize the bisecting process, you can use Git’s built-in git bisect log to see a record of all bisect operations:
git bisect log
This can be helpful if you want to review the process or document the steps.
In a nutshell
If you’re dealing with a bug in your codebase, there is a tool that will make life so much easier. It’s called git bisect, and it’s like a magical tool that helps you figure out where that bug came from.
You’ll be amazed at how much time you save, because you don’t have to go through every single commit by hand. It’ll become your best friend when it comes to debugging in Git. Plus, with the right approach, you’ll be hunting for bugs easily..







