In Defence of Gerrit

by Jared Norman
published March 13, 2024

The first team I joined in the tech industry was not doing what I understood modern software development to be. There was no CI/CD. There wasn’t a single automated test. They’d only recently adopted Git, but were using it primarily as a big save button. Some project histories were just a long string of arbitrary commits with the message “EOD”.

I was in my early twenties. I’d been programming actively for about ten years, but only as a hobbyist or in school. I had no industry experience. I’d been consuming all the programming material I could find to help me land a job. I was alarmed by the complete absence of “best practices”, but in no position to lobby for changes.

I eventually pushed them to change some of that, but in retrospect, what they were doing wasn’t nearly as bad as I thought at the time. The kind of work they did didn’t need robust code review. CI/CD would have been somewhere between difficult and impossible. What they were doing was fine for their needs, but I didn’t have the maturity to know that at the time. All I knew was that it flew in the face of what I had read a modern development process was.

My next job was the opposite. My time at what was then called “FreeRunning Technologies” (later renamed to “Stembolt”) shaped the developer I am today more than any other experience I’ve had.

My first real project at the company was integrating a Japanese payment gateway called GMO with a platform that would eventually power payments on Steam (yeah, that Steam) when it launched in Japan. No pressure for someone that had built his first production Rails app only months earlier.

I don’t recall any kind of project planning software or explicit process. There were no regular client meetings. There were just conversations with people that knew what the software needed to do, and then there was code review. Oh boy, was there code review.

We used Gerrit on the project. To this day, I have mixed feeling about Gerrit. It was horrible to use, horrible to look at, and horrible to explain to people. The workflow it enabled, on the other hand, was great.

I was expected to push up atomic commits that would be individually reviewed by more experienced developers. They could leave detailed feedback. I could then push up new versions of those commits, and Gerrit tracked them as separate versions of that commit. Reviewers could see what changed from my previous version of the commit and verify that I’d correctly addressed the feedback. If it took multiple rounds, you could diff arbitrary versions of a single commit to understand what had changed.

Gerrit technically supported something like branches, but we only used the feature when we absolutely had to. Every commit I authored had to pass CI before being reviewed, merged, and deployed individually. I knew nothing except continuous delivery. Everything was done incrementally. The only way to develop features was iteratively.

Rigid practices can teach you a lot. When I used Test && Commit || Revert to do some Advent of Code puzzles, I was never planning to keep TCR as a part of my daily practice. That wasn’t the goal. That exercise was a spiritual continuation of my experience with Gerrit, pushing me to find ways to work even more incrementally.

I look back on my time using Gerrit the same way that I look back on choosing C as my first programming language. I don’t generally recommend it to others, but I believe it made me a better software developer in the long run.

I miss Gerrit, even if I don’t actually want to use it again. I didn’t know it at the time, but it was teaching me things about developing software that are difficult to learn any other way and for which there are few (if any) good resources. Internalizing this approach has impacted every line of code I’ve written since. Incremental is smooth. Smooth is fast.