Not πŸ’©, here's how to write actually good commit messages (hint: It's not just adding commit-lint)

Jayant Bhawal - Jun 6 - - Dev Community
  • Update build file
  • Fixes dependency array
  • Refactor
  • Fix tests
  • The most famous: Update README.md (Thanks Github 🀦)

These are... some spectacularly amazing commit messages that I've actually seen in the last month. πŸ‘€
And... some of these are in our codebases too.
A bit embarrassing. I know. πŸ˜…

But this is not okay πŸ™…, and ideally I would want to rid the world of these.

"Sure, whatever. I don't think anything will change even after reading this blog."

For anything to change, I need to convince you that:

  • This makes a real difference that YOU can feel or measure
  • This makes a difference to someone else (which might be attributed to you later)

"Okay, get on with it. What do I do, and what do I get from it?"

Well written commit messages have some obvious benefits:

1. πŸ§‘β€πŸ’» Easier debugging

git blame makes it super easy to understand why a change was introduced, and makes it easier to ask the author relevant questions about it.

git blame isn't the first tool that's used during debugging, but for complex issues related to business logic, it's a tool that comes into play especially in medium to large sized companies. Some code simply evokes the question "Why was it written the way it was?" or "What purpose was this originally solving?". The answers to some questions don't lie in engineering, but in product decisions. And the author who wrote that has the best chance of knowing what decisions were involved.

Context-less debugging

Of course, git blame will tell you the author of a commit even without the need for fancy messages. So why is this part of this blog post?

Because how often do YOU as an author remember what a commit that you write 6 months ago was doing? Especially when it has a commit message like "Refactor"? Tough luck right?

I've seen more experienced devs write exceptionally helpful commit messages. I think some of them overdid it a little, but here's a rough example:

Fix crash on login screen due to null pointer exception.

- Checks for null values before accessing user profile data
- Adds unit test to cover this scenario
- Issue linked: BUG-5678
Enter fullscreen mode Exit fullscreen mode

Maybe it's a bit too much, but damn if it isn't obvious AF.
Now when I need to debug an issue in this area, being able to git blame for the author and context can be a lifesaver.
I say this with confidence because I used to be both on the giving and receiving side of this at Uber.

This has a serious added benefit which you might overestimate as you read this blog:

  • Saves time for you and your team, and reduces frustration

Debugging in the absence of context is PAIN. It's not even the kind where you can say "What doesn't kill you, makes you stronger." Because it just frustrates you.

You know it. Your team knows it. And that's why you try to understand who introduced "that bug" anyway and talk to them, only to find out they left the company 2 years ago. Good luck. 🀝

With this, you're leaving behind a legacy that would make people remember you fondly and wish they could work with you again.

"What if I use merge or squash commits?"

Some people have strong opinions for or against them.

All I'll say is, merge commits help to contain the context of a PR contained within a commit to a degree, but the individual commits themselves may not have much context associated with them if they are not well written.

And because a PR might involve a variety of dissimilar changes that work together to ship a feature, and the constituent changes might have their own context for being written that way, squashing them might effectively muddle all that context making it difficult to draw inference from the commit history.

But perfectly functional software is written either way. As long as you and your team agree that your way of merging PRs works for you with minimal issues, who I am I interfere?

2. πŸ” Easier code reviews

If your org doesn't care too much about making code reviews be painless and not make it feel like a chore, you need to share this with your people:

Now, how do better commit messages help with code reviews?

From Middleware's analyzed data, an average PR in a mature codebase (active repo, past its setup phase) can be around 300 lines.

That's a lot of lines. And most of these changes are not happening in the same file. Neither should they. 300 lines is on the upper end of a file being readable (it's not a rule set in stone though).
It's a near-guarantee that different kinds of changes are being shipped in these PRs that NEED to go together for the desired functionality to be shipped.

If you can't make a smaller PR for any reason, you can make smaller commits in the same PR. Make each commit contain the smallest piece of logically isolated change, such that the commit message can sufficiently explain what it contains. Because you don't want to write a commit message that's a paragraph long either, you'll need to create a commit that's small enough that roughly 50-60 characters can explain what it's about.

Now, the reviewer can review your PR commit by commit without having to follow up with you for everything or wondering why something was written the way it was (if they do, they'll have to ask you [the author], you know? Do you really have much time for that?).

Meaningful commit messages

3. πŸš€ Better release notes!

Or if you're not generating "release notes" exactly, then it's still better documentation of the history of your project!

Github, specifically, also allows you to generate release notes for your project automatically from your commits. And release notes are seen by a LOT of people to get an idea of what fixes or features new releases contain.

See the releases section of the React codebase, and see how many reactions each release note has!

React release notes

Clearly release notes matter to people. And by writing well written commits, you're saving yourself effort from writing release notes.

And finally...

4. πŸ‘₯ Encourages better practices across the team

Use the force Luke

When team members see the benefits of well-written commit messages, they are likely to follow suit. This can lead to a more disciplined approach to code commits across the entire team, encouraging a culture of clarity and precision. This is the kind of stuff that makes an SDE1 act think and act like an SDE2.

Here's another example of such a commit:

Update permissions routing layer to handle subroutes independently.

- TKT-1234
- The permissions routing logic was previously coupled with its nested routes
- This change will allow you to move subroutes to any other parent route without also having to make any changes to how the permissions for that subroute are defined
Enter fullscreen mode Exit fullscreen mode

In environments where multiple people work on the same project, consistent and detailed commit messages can align everyone's understanding and expectations, reducing potential conflicts and misunderstandings, without needing as much time to block for context sharing.

And of course, if you can be the champion of better commit messages in your team or organization, you'd love to get the credits for any benefits that brings, won't you? πŸ‘€

Teams that can work asynchronously, is a team that can work efficiently. No one wants your teams to have bottlenecks on stuff like this. πŸ‘Œ

UPDATE:
I really should have covered this earlier, but if you're convinced about the idea of using good commit messages and are using it in some form regularly, you might be ready to take the next step.

The next step would be to have a standard way and structure of writing commits in your org. Adhering to standards can involve a bit of a friction in your experience, but it can prove to be fruitful in the long term.

Presenting, Conventional Commits!
Thanks @taosif7 for reminding me of this!

GitHub logo conventional-commits / conventionalcommits.org

The conventional commits specification

ConventionalCommits.org

Conventional Commits

This repo is the home of the Conventional Commits specification.

Repo Layout

We use HUGO as static site generator, so we use the directory structure HUGO proposes.

Our implementation

  • ./content: contains all the versions of the specification.
  • ./content/next/: contains the version of the specification (where all the changes SHOULD be made).
  • ./content/**/index.[lang].md: contains the content of the specification, if a language is specified it's a translation.

Contributing

We'd love your help refining the language of this specification, fixing typos, or adding more translations. Please don't hesitate to send a pull request.

Adding a translation

  1. Create a new file in ./content/version/index.[lang].md using the hugo command hugo new [version]/index.[lang].md.
  2. Ensure all files have the appropriate fields required (see others as an example)..
  3. Add the language to the config.yaml file (see others as an example).

Running project locally

There's a docker-compose.yml file ready that will help you to…

Conventional Commits is a specification for writing great commits in a standardised way. There are many tools which rely on commits written following this spec which may be able to automate even more things for you in terms of release notes, feature updates, separation of commits/PRs by the nature of the work involved in them (such as refactors, chores, fixes, features, etc.).

It's absolutely the next thing you should at least give a look.

Wrapping this up

Good commit messages have serious GAINS. πŸ’ͺ
Gains for you, and the teams that you're a part of.

Less time spent debugging, fewer frustration moments, better documentation, automatic release notes, etc.

As a side-effect of all those improvements, you might even notice faster code deliveries, lesser wait time in reviews, fewer rework cycles!

Go on! Take credit for all the efficiency improvements you introduced!

And see exactly how much of a gain it was for your teams by using a productivity intelligence tool, such as Middleware! πŸš€

GitHub logo middlewarehq / middleware

✨ Open-source dev productivity platform for engineering teams ✨

Middleware Logo

Open-source engineering management that unlocks developer potential

continuous integration Commit activity per month contributors
license Stars

Middleware Opensource

Introduction

Middleware is an open-source tool designed to help engineering leaders measure and analyze the effectiveness of their teams using the DORA metrics. The DORA metrics are a set of four key values that provide insights into software delivery performance and operational efficiency.

They are:

  • Deployment Frequency: The frequency of code deployments to production or an operational environment.
  • Lead Time for Changes: The time it takes for a commit to make it into production.
  • Mean Time to Restore: The time it takes to restore service after an incident or failure.
  • Change Failure Rate: The percentage of deployments that result in failures or require remediation.

Table of Contents

πŸš€ Features

…
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player