How to write helpful git commits and descriptive pull request titles

Last updated 5th September, 2023

The backstory

My team and I experienced a bit of drama a few weeks back when a piece of code that was deployed to production caused some unwanted side-effects for our users. The developer that authored that code was on leave and we couldn't contact him easily, so we decided that we should revert that piece of code. Unfortunately, due to the nature of the changes, we needed to revert just a small chunk of that code, and that meant finding the pull request and commits and using that to work out what needed to be reverted.

This was a couple of weeks after the change went live, and our team merges dozens of PRs a day, and pushes hundreds of commits a day - so the changes immediately got swamped in the history (I'm sure you can guess where this is going 🙄).


The problem

We spent over an hour looking for the code that caused the issue, then an additional hour trying to figure out if that was the only change needed to revert, and if that revert could cause more problems that it solved.

This was the offending commit...

An image of a commit that simply says 'spacing'


The Solution

After we patched the issue we discussed the issue and quickly came to a consensus that we could have fixed the issue faster, had the commit and PR been named correctly.

So we came up with a few guidelines that we would stick to a as team to make sure that all our historical code is findable, understandable and fast to author.

Conventional commits

We follow the Conventional Commits guidelines, this provides a lot of benefits, I will not list them all exhaustively, but here are our favourites:

  1. It forces that our commits stay consistent across the team. This ensures every developer knows what to expect when digging through git history.

  2. It improves searchability, with conventional commits, you can scope your commits with an "area" that the commit refers to, which can then be searched in git history. e.g. feat(email): adds method to set from name.

  3. They are quick to author. You don't have to write an essay, you just have to state what, and most importantly why.

Why not what

We decided that the why is more important than the what. Take this example; fix: filter null values. Sure, we know that the code change probably relates to remove null values from some kind of collection. But how much does that actually help us? If you're trying to figure out why a bug has popped up - this won't help you much if you're searching for culprits. fix: filter null recipients in email send however tells you what area of your logic the change is effecting, and to a large extent -why. Obviously we do not want to send emails to null@null.null 😁. So for the cost of 3 extra words, you could save yourself an hour of digging too.

Descriptive pull request names

Similarly to good commits, PR names matter when trying to find some historical change or feature that has bubbled up to the surface. They have great scope for showing a history of changes to your repository. At Teemill since implementing these guidelines we use our pull request names to generate a changelog that we curate for our users to inform them of new features and fixes. This forces our team to maintain a high standard of naming PRs well as they'll end up being shown to our users!

An example of a bad PR:

Example of a bad PR name. 'Fixed dashboard load issue'

This is non-descriptive and unrelatable, it means little to our users and is too generic to be useful when searching

A better example:

Better PR name example. 'Fixed an issue on the dashboard that caused load time to increase by ~1 second'

If you read this from the perspective of a user, its now meaningful - you've just sped up their workflow by up to a second. It also increases the searchability of the PR.

No comments yet…

DevInTheWild.

Login To Add Comments.

Want More Like This?

Subscribe to occasional updates.