You don't have time to NOT learn Git Bisect

You don't have time to NOT learn Git Bisect

As people who write code, many of you will have taken on little projects over the potentially extended holiday period. It's great when you have that additional time and can power through. The family is relaxed, the kids playing with some new game, and you have a few hours to make headway into your new project.

Or, if you're like me, I planned to work on a new project and thought I'd just fix a little bug that had been annoying me for months first in something else. But there was a problem. I didn't know the framework (Angular), which was an older version. I knew I didn't have the time to do a framework upgrade. I didn't expect that would fix it anyway.

The issue I faced was a regression. Something that worked previously but didn't work today and hadn't worked for months.

OK, go on, what's the project?

Do you like Star Trek? Yes? You can keep reading. (You can also stay if you don't... I guess. Just this once). If you spend time in board gaming or tabletop gaming circles, you probably know about the X-Wing miniatures game. Star Trek Attack Wing is the Star Trek answer to that same idea with a few differences.

You pick some ships, you pick some upgrades, you move the ships, and pew pew pew (roll dice). Great fun! But sadly, it isn't as popular as it once was, and I'm not sure ANY stores are running events now. Stock is not plentiful, and official games in the UK, at least, seem to be over.

With few players and a less-than-quick setup time (picking your ships and upgrades), finding someone to play against in person is hard. Tabletop Simulator to the rescue! Tabletop Simulator (or just TTS for short) allows people to play all sorts of board games and miniatures games, with communities creating their own mods. For the most part, it functions as if you were sitting at a table, with some additional ease-of-use automation like making movements, which is pretty neat.

Finding your ships and cards in the game could be tiresome. Luckily, a web-based project called Utopia makes building a fleet super easy and even has an export function that you can paste into the TTS mod game to set up all your ships and cards. Pretty neat!

Utopia has the ability to limit what you can select to what you own, and you can export and import the list of owned ships. This is ideal if you want to build some fleets for playing in person but don't want to trawl through your physical cards. Just one problem, though... the import feature was broken.

I can debug this, right?

As an experienced web developer, I have debugged some complex workflows and even dreaded race conditions. Even not knowing the framework, I felt confident I could probably debug this problem in browser.

I had a few hours spare... how long could it take? I set breakpoints, and I stepped through the code... Slowly finding each part seemed to be working. There were a few "magic jumps" or hooks (I think) where I couldn't really step through code properly. After a few hours, I'd determined that code seemed to do what it should, but it still didn't work... somewhere.

Having worked with Vue and React, I was used to pretty helpful developer tools in the browser. Turned out that the version of Angular I was using wasn't supported properly by the debug tools, or at least that's the only information I could find on why it wasn't working correctly. And, even if it was, I still wouldn't have found the problem.

Let's validate those assumptions

I assumed I would be able to step through the javascript code files to find the problem. Seemed like a pretty reasonable assumption to me. I also assumed, given I stepped through, put in breakpoints, and read and understood the code, that I was looking at all the code related to the broken task. I was wrong.

I decided I was either going mad or there was something I didn't know elsewhere that the debugger wasn't reaching because of all the hooks and jumping around.

I needed to determine the commit that caused the regression (the functionality to break again). Luckily, the project is in git, so this task would be easy enough with git bisect!

If you've never come across git bisect before, it's part of the standard git CLI that allows you to find a specific commit using a binary search algorithm. I found an older commit and ensured it was working sufficiently long ago. When you're ready, you start by doing git bisect start.

Checkout the commit that's broken, then do git bisect bad. Checkout the commit that was working, then do git bisect good. Git bisect will then tell you how many steps you'll need to take to find the commit (binary search, remember). It will checkout each commit required, and you just need to run your test (manually, in my case) and then follow up with git bisect good/bad for the bisecting to continue. It's really pretty smart.

If you want extra credit, and you have an automated test you can run, you can make it more automated by using git bisect run. Sadly, though, I needed to manually do the testing browser. I'm sure I could have scripted it, but I didn't have the time to learn something new.

You do have to make sure that you reinstall the project's dependencies, which might make the steps slow if it's a big project. A short while later, I had the causal commit. I had checked most of the files, but looking at the html file couldn't hurt, right?

Javascript in HTML... should have known

I don't know why, but I just didn't expect to see causal code in the HTML files. I thought Angular was primarily to do with templating, and hadn't considered it would do filtering logic.

Opening the HTML file that changed as part of the causal commit, it took hardly any time to identify the problem... A single equals sign was being used for a comparison check, which is an easy error to make. Maybe a typo.

Luckily, easy and uncomplicated to fix.

A brief holding of breath, and it worked. Pushed to remote and PR filed.

So, what did we learn?

It's not uncommon to need to deal with legacy code. By this, I mean code that was written last week or by anyone else because the chance that it's well-documented and commented, is low. The author might not be around to answer questions, and you may need to fix that bug right now for a client or customer.

When you don't know what you're walking into, finding the commit/change that caused the regression will narrow down your potential pool of code to look at and stop you from making false assumptions about the likely fix.

If you've not used git bisect before, maybe now is the time to learn. The next time you're all crowding around to try to fix a regression bug that made it into production, you'll be able to offer a solution to vastly speed up finding the cause.

If you're interested, here's the GitHub Issue and Pull Request

In the end, adding just two characters fixed the bug. Maybe if I'd built the system myself, I'd have had more of an idea of where to look, but there's no guarantee, especially if that code hasn't been touched for 6 months!

As an aside, if anyone wants more information about Star Trek Attack Wing or playing it in TTS, I'd be more than happy to direct you! Just reach out or comment.

Photo by Ricky Kharawala on Unsplash

Did you find this article valuable?

Support Ben Hutton by becoming a sponsor. Any amount is appreciated!