Debugging with Git bisects
Have you ever introduced a bug into your codebase and then spent hours, maybe even days, trying to figure out exactly when it happened? Scrolling through endless commits, comparing files, and feeling increasingly frustrated? If so, you’re not alone!
Luckily, Git has a powerful tool that can significantly speed up this debugging process: git bisect
. Think of it as a detective for your code, helping you pinpoint the exact commit that introduced a problem.
This article will guide you through the basics of git bisect
with a clear and complete example, making it easy for beginners to understand and use.
What is Git bisect
git bisect
works by performing a binary search through your commit history. You tell Git a “bad” commit (the one where the bug is present) and a “good” commit (a commit before the bug existed). Git then checks out a commit halfway between these two points. You test your code at this commit and tell Git whether it’s “good” or “bad”.
Git repeats this process, narrowing down the range of commits until it isolates the single commit that introduced the bug. It’s much faster than manually checking each commit one by one!
Why Use Git Bisect?
How to Use Git Bisect
Let’s imagine you’re working on a simple web application. Yesterday, everything was working fine. Today, you notice that the “Add to Cart” button is no longer functioning. You have a few commits since yesterday, and you’re not sure which one broke it.
Here’s how you can use git bisect to find the problematic commit:
Start the Bisect Process:
Open your terminal in your Git repository and start the bisect session:
1 | git bisect start |
Mark a Known Bad Commit:
The current state of your main branch (or whatever branch you’re working on) is where the bug exists. Tell Git this is a “bad” commit:
1 | git bisect bad HEAD |
HEAD
refers to the current commit you’re on.
Mark a Known Good Commit:
You remember that the “Add to Cart” button was working correctly in the last release, which was tagged as v1.0. Tell Git this is a “good” commit:
1 | git bisect good v1.0 |
or you can specify a commit hash if you know it or branch name.
Git Starts the Search:
Git will now check out a commit somewhere in the middle of the commit range between v1.0
and HEAD
. You’ll see output similar to this:
1 | Bisecting: 7 revisions left to test after this (roughly 3 steps) |
Git has checked out the commit with the hash abcdefg
.
Test the Current Commit:
Now, you need to manually test your application at this specific commit. In our example, you would run your web application and try clicking the “Add to Cart” button.
Tell Git if the Commit is Good or Bad:
If the “Add to Cart” button is working at this commit:
1 | git bisect good |
If the “Add to Cart” button is still broken at this commit:
1 | git bisect bad |
Repeat the Process:
Git will continue to narrow down the commit range by checking out another commit based on your “good” or “bad” feedback. You’ll repeat steps 5 and 6: test the code and tell Git whether the current commit is good or bad.
Git Finds the Culprit:
Eventually, Git will isolate the single commit that introduced the bug. You’ll see output like this:
1 | Bisecting: 0 revisions left to test after this (roughly 0 steps) |
Congratulations! Git has identified the commit with the hash hijklmn
as the one that introduced the broken “Add to Cart” functionality. The commit message even gives a hint about what went wrong!
Reset Git Bisect:
Once you’ve found the problematic commit, you need to reset your Git repository back to its original state before the bisect process:
1 | git bisect reset |
This will return you to the branch you were on before you started git bisect (in our example, likely main).
Conclusion
Using git bisect
can save you a lot of time and frustration when debugging your code. By automating the process of finding the commit that introduced a bug, you can focus on fixing the issue rather than searching for it.