Better Git commits
Knowing what changes to commit and when to commit them is a valuable skill that comes in handy either if you are working in a team or by yourself. In this brief article I’ll try to describe some common best practices.
Atomic commits
First of all, a commit should be atomic, namely it should be about one task or one fix. If you have changes which are completely unrelated, you should have different commits for each one of them.
Squashing? Yes please!
It’s good to commit early and often, but you probably don’t want to end up with a zillion tiny commits on a public branch. It’s very hard to read the history of that branch and go back to a specific snapshot where you (or another developer in you team) introduced the changes. You can instead commit many times on a feature branch, rewrite your local history by squashing several commits together into a reasonable number of commits, and only then push your squashed commits to a public branch.
There are also some other strategies, but I have to admit that I’m still not very comfortable with them.
The commit message
Writing a good commit message is an important skill to have, even when working in a small project. Remember that the person who is most likely to read that commit messages is the developer who wrote it, so it makes perfect sense to stop for a while and think carefully about what to write when committing some changes. It certainly takes some time to craft a good explanation of the changes introduced with a particular commit, but I think it’s time well spent.
It’s tempting to use the shortcut git commit -m
, but I try to avoid it. It makes me feel bad every time I can’t think about a way to express my changes into 50 characters or less.
A commit message should start with a brief summary of 50 characters or less. This short text serves the purpose of explaining what these changes are about. Use the imperative mode (e.g. Fix issue #1234), not a past tense (e.g. Fixed issue #1234). This is consistent with the commit messages generated by commands like git merge
. Also, don’t forget to use uppercase for the first letter in the summary.
After the summary you should leave one blank line and write a more detailed description about our changes. It’s a good idea to wrap this text at 72 characters per line. The length of this text depends on the commit itself: if you are committing only some small changes you might skip it altogether, while if you need to explain thoroughly the reasoning behind a given design implementation of a class or a function it might cover several lines of text.
If the description is really long, you can divide it into several paragraphs and leave a blank line after each one. If you have some bullet points, you should keep the indentation consistent.
A good commit message should explain what you did (in the summary) and why you did it (in the description).
Here is an example:
Why 72 characters? And how to do it?
The reason behind 72 characters is that git commands like git log
don’t do any special wrapping, so if you enter them in a 80 column terminal, and if you need to reserve 4 columns for left indentation and 4 for right indentation, you are left with 72 columns.
A really handy way to have syntax highlighting and automatic text wrapping is writing commit messages using Vim. You can set Vim as the default editor for git either by opening a terminal and entering git config --global core.editor "vim"
, or by locating our .gitconfig file (it’s in the home
folder in Linux) and adding an entry in the [core]
section (or create that section if is missing).
# .gitconfig
[core]
editor = vim
Then you need to configure Vim. Locate the .vimrc
file in the home
folder (or create one if it’s missing) and copy/paste the content of the example file you can find here to have 50 character limit on the first line, text wrap to 72 characters for the commit message description, syntax highlighting and line numbers.
If you are curious why you can’t find these settings in the text you just pasted in the .vimrc
file, it’s because Vim understands automatically that we are writing a gitcommit file, and uses a specific setting with them. We can check these settings by typing :set
in command mode while we are about to commit our changes. We will see some entries like filetype=gitcommit
and textwidth=72
.
References
Here are some additional resources on writing great commit messages: