This article explains how to make good commits in version control systems such as git. First, I'll explain the purposes of creating commits, then I'll show you how to make good commits, and finally, I'll explain how to write good commit messages. Please note that I won't write anything easily found by searching "git commit message".
We continually change artifacts (documentation, source code, etc.) in software development over time. Version control systems, including git, manage those changes and allow us to capture a moment in between the time by a commit.
One of the purposes to capture is to preserve the moment when the software is working correctly. If a bug occurs in changes from that moment, you can go back to the previous commit to recover the working state. If you find a bug in a commit that should work, you can go back to one more commit. If you don't find the same bug there, you can identify that the bug occurred in the next commit.
The other purpose is to place a message at a moment and record it. The message helps you remember the reason for the change in the commit afterward, and other people can understand your work by investigating your commits.
Another purpose is to decide when to share your changes with the team members. In version control systems, you need to make commits to share your changes with others; in git, you need to push them to a shared repository, but whatever the case, you need commits to share your changes with others.
Thinking about the purpose of a commit makes it easier to understand the criteria for a good commit, i.e., which moment of the ever-changing artifacts you should capture.
A commit that preserves the working state and helps us track down bugs should be made when you can assume the software works properly. You should try not to have more than one bug in a commit to make it easy to identify which commit a bug resides.
A perfect moment to make a commit is the next time the software works correctly, after making small changes that are unlikely to introduce multiple bugs from the previous commit.
From this point of view, a commit with absolutely no room for bugs is useless because it only adds another step when you track down a bug. It's really unnecessary if it doesn't meet other purposes described below.
Of course, a commit to place a message at a specific moment should be made when there are no changes unrelated to the message. And the message must make it easy to understand the commit both for you and others.
The message should have one thing. So, if it is something like "A and B", the commit should be divided into two. And the message should be concrete enough to narrow the differences included by the commit.
A commit with a few thousand lines of changes represented by a vague message is not helpful to anyone. On the other hand, even if a commit has thousands of lines of changes, it is still helpful if it has a concrete message like "Change the method name A to B".
When you make a commit to tell other members about your changes, it is even more important to place a concrete message and make the changes small. Since you are asking another member to review your commit, you should not make the commit something even you don't feel like reviewing. Of course, if there are team rules about commits, you have to follow them.
You should make such a commit when the development process in your team requires it. For example, if your team uses an issue management system, such as GitHub issue, you need to create a commit when you solve the issue assigned to you, and you must follow the rules in your team to tie your commit to the issue.
Because a commit is a snapshot of a moment, the accompanying message should either describe the changes that occurred between last and this time, describe the event that triggered the snapshot, or both.
You should summarize the commit in the first line of the message. Because many version control systems, including git, only show the first line of the message on the commit log in the briefest format. This format provides a bird' eye view of the many commits and becomes more valuable by good first-line summaries.
In git, there is a convention requiring us to write one line summary with less than 50 characters at the first line. It's a good practice. Though the line can be longer than 50 characters, it shouldn't be too long because humans have a limit of how many characters they can read at a glance.
On a version control system in your team, your commit messages are messages to other members, and the commit log is an essential component of communication in the team. The commit log is like a bulletin board to help the communication, and the messages placed on it should be brief and to the point.
A suitable manner of writing the message depends on the product being developed and the team developing the product. Still, you should write "what has been done" in an imperative form, "do something" to summarize your changes. The candidates as the verb are shown below.
Examples of messages are "Fix a bug in the signature algorithm.", "Improve speed of displaying the user list.", "Update models to reflect changes in tables", "Change ConnectionCreator to ConnectionBuilder".
As many projects are doing, prefixing a message with one or more tags to identify the related issue, module, or subsystem, can help narrow down the scope of the "what" in a short number of characters.
If this is necessary and you can keep it short, you may add "what for". If it becomes too long, you can move the details to the second line (the third line after a blank line in git) or later. And for a commit tied to an issue on an issue management system, you can leave the details in the comments of the corresponding issue.
I started by explaining the purposes of commits and showed you how to make excellent commits. By the way, I wrote this article to encourage my current team members to improve the granularity of commits and the quality of their messages. Many sentences started with "you should do," but most of them mean just "I would like my team members to do," so please forgive me for that.