Skip to content

Have you ever felt like pulling your hair out as you struggle to understand a few lines of code? The frustration builds as you go through the code, desperately seeking any hint or context that might offer some clarity. You're on the verge of giving up, but as a last resort, you turn to git blame to gain more insight into the code change. Of course, you end up with a commit message like "Fixed bug," which doesn't really help at all. Trust me, I know that feeling all too well. You're not alone in these struggles.

When Commit Messages Go Wrong

I have encountered countless situations where a well-crafted commit message would have been tremendously helpful. I first discovered the power of meaningful commit messages when I started using Git. Coming from Apache Subversion, where I was used to seeing informative and context-rich messages, I found it disappointing that many commit messages in my new project were far from ideal. It felt like they were added just for the sake of having a message, offering little to no context. Perhaps the company was new to using Git, or their standards were not up to par. It made me spend countless hours debugging, where a commit message could easily have told me the purpose of a few classes.

Another time, while working at a different company, I was determined to understand the inner workings of an optimization algorithm. After spending days trying to understand complex mathematical equations and cryptic variable names, I turned to the commit logs, hoping they would shed some light. Unfortunately, the commit messages were just as cryptic as the code itself and provided no useful insights. Faced with tight deadlines, I had no choice but to abandon my efforts, leaving me with a haunting sense of defeat.

When Commit Messages Are Useful

A well-written commit message can be just as valuable as the code itself. I learned this firsthand when dealing with a security vulnerability in an outdated Maven library. The easiest fix was to find a replacement, but the existing code provided no hints about why the library had been chosen in the first place. Was it for performance reasons? Compatibility? A specific feature?

Fortunately, the commit messages told the full story. One message explained the reasoning behind adding the library in the first place, while another detailed why a previous attempt to replace it had failed. With this context, I quickly ruled out incompatible alternatives and found a suitable replacement in record time. Without those commit messages, I would have been left guessing.

You might not think to read commit messages during code reviews, but I find them invaluable. In the past, I primarily conducted code reviews asynchronously. Reading commit messages has helped me significantly, allowing me to understand the purpose and context of code changes more thoroughly. As a result, I have fewer comments and need to sync with the author less frequently, saving both of us time.

Advantages

Throughout my career, experience has taught me that meaningful commit messages have benefits that extend far beyond the immediate change. There are several advantages to writing good commit messages:

  1. Readable History: Good commit messages provide a story that goes beyond just versioning, explaining how the solution came to be.
  2. Peer Review: They aid in code reviews and provide insightful information about pull requests.
  3. Easier Onboarding: New team members can learn a lot by reading commit messages instead of trying to decipher the codebase.
  4. Simplified Refactoring: Knowing exactly what the code does makes refactoring easier. While tests are primarily relied upon for this, commit messages provide additional context.
  5. Team Collaboration: Clear commit messages enhance communication among team members, ensuring everyone is on the same page regarding changes and their rationale.
  6. Project Management: They help track progress and changes over time, which is valuable for project management and retrospectives.
  7. Compliance and Auditing: In regulated industries, well-documented commit messages can be crucial for compliance and auditing purposes.
  8. Continuous Integration/Continuous Deployment (CI/CD): In automated CI/CD pipelines, good commit messages can trigger specific actions or provide useful information for release notes. GitLab and GitHub allow responding to certain specific keywords in your commit messages. An example would be the deployment, which only runs when the commit message contains the word "Deploy."

7 Rules for Good Commit Messages

Often, developers don't spend meaningful time thinking about commit messages. As a result, Git is not used to its full potential. The quality of a commit message is evident when you read it, but usually, not much context is provided. You might have encountered commit messages like these:

  • adding controller classes
  • added new line
  • refactoring

These messages do not provide meaningful context, even if they reference a ticket in the message. A good commit message should complement the code, providing context that isn’t immediately obvious from git diff. The goal is not just to describe what changed, but why the change was made. I find this article very helpful when it comes to writing good commit messages. To briefly summarize it, the author outlines seven rules that help create meaningful messages:

  1. Separate the body from the subject with a blank line. The text up to the first blank line in a commit message is treated as the commit title, and that title is used throughout Git.
  2. Limit the subject line to ideally 50 characters, but no more than 72 characters. Keeping subject lines at this length ensures that they are readable, and forces the author to think about how to capture the essence of the change.
  3. Capitalize the subject line as you do with any title in general.
  4. Do not end the subject line with a period, since it is meant as a title.
  5. Use the imperative mood. When you write your commit messages in the imperative mode, you’re following Git’s own built-in conventions.
  6. Wrap the body at 72 characters per line. Git never wraps text automatically. When you write the body of a commit message, you must mind its right margin, and wrap text manually as you do when writing or formatting code. It is about readability.
  7. Use the body to explain what and why to give context about the change.

Applying these rules to the bad examples above, we get something like this:

OriginalBetter Commit MessageEven Better Commit Message
Adding controller classesAdd API contract for lookupInclude the necessary methods to interface with the lookup service
Added new lineFix lint failureCorrect linting errors to maintain code quality
RefactoringExtract common logic to reduce duplicationMove common functions to utility file, reducing redundancy

Aren't these much better to read? They immediately give you an idea of what the code was meant to do. I am confident that this approach can reduce the time spent looking at code significantly. To be fair, for this to work, you also need to ensure your commits are properly sized, or rather, change only one aspect of the code—so-called atomic commits.

Incorporating these Rules

Now that we understand why commit messages matter, let's look at two ways to ensure we consistently follow best practices:

  1. Use a Git commit message template.
  2. Use a commit linter.

Commit Template

Defining a commit template for yourself or your team is a great way to apply these rules. Instead of having to remember them or spending time searching for a meaningful message, Git allows you to define a message template. This template, when done effectively, helps with writing commit messages, so the next time you spend less time searching the code for clues. However, this approach encourages good practices but doesn't strictly enforce the rules.

It is quite simple to set up a message template by following these three steps:

  1. Create a file with the template at $HOME/.commit_msg_template.txt:
[Ticket-#]: Short description of commit (50 chars)

Longer explanation of commit (72 chars per line)
  1. Set the template by configuring Git's global settings:
git config --global commit.template $HOME/.commit_msg_template.txt
  1. Start making new code changes. Whenever you want to commit, you will already have the desired format, similar to git merge, where you also have a template in place.

Example:

[TICKET-123]: Add refresh token grant

Implemented refresh token functionality (OAuth2 grant) for user authentication,
ensuring secure and seamless login and access control.

Commit Linter

To strictly enforce the good commit message practices mentioned, a linter might be the solution. While I haven't personally used one for commit messages yet, my colleagues recommend Conventional Commits. It's designed to help teams maintain a structured commit history, although its functionality may vary depending on the programming language. Consider exploring commit linter tools to further enhance your workflow!

Conclusion

I strongly believe writing good commit messages is not just about following best practices. As experience has taught me again and again, applying these rules will make everyone's life easier, whether during code reviews, debugging sessions, or refactoring code. By following these guidelines, you can turn Git into a powerful tool for documenting and understanding your project's history.

Ready to transform your commit messages? Start with a template and notice the difference in your development workflow. Happy coding!

Published by...

Image of the author

Jernej Klancic

Visit author page