Bisecting bugs with binary search
The problem
A couple of days ago while working on my blog, I found out that the full-text site search didn’t work anymore. On the desktop, I couldn’t see the search UI at all as seen in the following screenshot.
And mobile search UI looked pretty strange with two search inputs…
Something was wrong and I needed to get to the bottom of it. At the time I noticed the issue I was setting up astro-compress to compress static assets after the build. I thought maybe something went wrong during the compression so I tried excluding pagefind
(Starlight uses Pagefind to implement full-text site search):
Neither excluding these assets nor disabling the compression altogether helped. It was high time to turn to git bisect for help.
Bisecting the bug with Git
git bisect is (obviously) a git command that uses binary search to find the commit that introduced a bug. It does so by asking for good
and bad
commits and once these commits are identified it starts halving the commits between these until the commit that introduced the bug is found.
Locating and fixing the bug
I knew that the latest commit had the bug so it was time to start the bisecting process so I ran the following command in the terminal:
Here is the output of the command:
Notice there is no need to mark the very first commit as bad
when starting to bisect as git bisect start
already assumes that the current commit is bad
. All I needed was to find a good
commit and to do that I went back to the last known good commit (by git checkout
ing older commits and checking for the existence of the bug) and ran git bisect good
:
As you can see above I’ve git checkout
ed to the 69da06aa1c9e2d620ac3ebba25ddf956c31d8cf5
commit and as it did not contain the bug I marked it as a good commit with git bisect good
. Git immediately started the bisection process by checking out the d1eef597555defb5c235013142a42c82fed8120b
commit and even showing a rough
estimation of the number of remaining steps.
From now on here is the algorithm I followed:
After a few iterations as the final step git
presented me with the following commit:
Interesting. The Enhance current header for mobile experience
commit is exactly where I made some changes to the header component but I didn’t change the search functionality at all. Or so I thought…
OK, let’s see what this bad
commit did with git show fb05597e11b01673c133b977542c9360b9ad2619
. For the sake of brevity I won’t show the whole output of the command but here is the relevant part:
Hmm, at this moment all I had were assumptions but one thing I saw was I had two “instances” of <Search />
(remember the mobile search UI had two search inputs?) one of them should only be visible in mobile view the other one in desktop view.
I mistakenly thought that it would be OK to do this and then just use CSS to control the visibility of the search UI but Starlight had another idea so I attempted to remove the second instance of <Search />
and that fixed the issue. Afterwards, I simply polished the UI and committed my changes. Everything worked as expected and I deployed my changes 🚀
Conclusion
git bisect is an incredibly powerful tool in the git arsenal for finding bugs if git is used correctly. It takes some discipline and practice to keep commits atomic and small but it’s worth it in the long run. I highly recommend using it.
I hope you found this article useful. Until next time 👋