As a software developer, your core skill is writing patches, and applying them on an existing code base to make the software better.
Software is build patch by patch. To be a good software developer you need to know:
- exactly what a patch is,
- how an ideal patch looks like and
- how to use git version control software to manage patches.
What is a patch
A patch defines the changes to be made to the code base. It is basically a list of what code lines to add, remove or modify in a code base. Each patch always also has an author, a timestamp when it was written, a title that describes it and a longer text body that explains why this particular patch is good and applying it on the code base is beneficial.
Example:
Author: Otto Kekäläinen
Date: June 22nd, 2022 08:08:08
Make output friendlier for users
Add line break so text is readable and add a 2 second delay between
messages so it does not scroll too fast.
--- a/demo.c
+++ b/demo.c
@@ -8,7 +8,8 @@ int main()
{
for(;;)
{
- printf("Hello world!");
+ printf("Hello world!\n");
+ sleep(2);
}
return 0;
}
How to make a patch
You can make a patch by simply copying a file, changing something in it, and then comparing the copy to the original file using the command diff and saving the output.
$ cp demo.c demo.c.orig
$ nano demo.c
$ diff -u demo.c.orig demo.c > demo.patch
$ cat demo.patch
--- demo.c.orig
+++ demo.c
@@ -8,7 +8,8 @@ int main()
{
for(;;)
{
- printf("Hello world!");
+ printf("Hello world!\n");
+ sleep(2);
}
return 0;
}
The patch can be sent by email or uploaded somewhere. After that anybody can download the patch, read it, and apply it to their copy of the code base using the command patch.
$ grep Hello demo.c
printf("Hello world!");
$ curl -O https://…/demo.patch
$ patch -p0 < demo.patch
patching file demo.c
$ grep Hello demo.c
printf("Hello world!\n");
Now this is not very fast nor convenient, and therefore we use git, a version control software that automates all of this. In git we tend to talk about git commits, which basically just means a patch that has been applied on a code base.
Examples of a good git commits
A good git commit typically has these characteristics (adapted from the Git Pro book):
Capitalized, short summary of what the change is
More detailed explanatory text that focuses on the 'why' to motivate
the change. Use present tense and imperative format (write "Fix bug",
not "Fixed bug"). Wrap it to about 72 characters or so. The blank line
separating the summary from the body is critical.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, followed by a
single space, with blank lines in between, but conventions vary here
- Use a hanging indent
Here are a couple of real-world examples in pure text form:
From MariaDB@ff1d8fa7:
Deb: Clean away Buster to Bookworm upgrade tests in Salsa-CI
Upgrades from Debian 10 "Buster" directly to Debian 12 "Bookworm",
skipping Debian 11 "Bullseye", fail with apt erroring on:
libcrypt.so.1: cannot open shared object file
This is an intentional OpenSSL transition as described in
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993755
From MariaDB@2c529441:
Deb: Run wrap-and-sort -av
Sort and organize the Debian packaging files.
Also revert 4d03269 that was done in vain.
Five requirements for a good commit message
In order of importance:
1. Commits should be atomic
The first and most important thing about a good patch or a commit, is that it should be a self-standing change. If a commit fixes a but, it should not at the same time add a new feature or fix some other completely unrelated bug. If you add a new feature, the same commit should ideally also add automatic tests for the feature to ensure it won’t regress, and the same commit should update the documentation to mention the feature.
If your changes are not properly scoped and self-standing, you might end up in a situation later on where somebody decides to revert or reject the commit that introduced a new feature, but miss removing the tests or documentation about it not, if they were added in separate commits.
There is no clear rule on what is the optimal scope for a commit, it is something you will learn by experience. Sometimes it makes sense to have several separate changes in one single commit simply because each one of them being so small. In other cases one single logical change might span multiple commits, because it was perhaps clearer to move or rename files in one commit and then update their commits in another. This is something you will just have to learn over time as you become a more experienced software developer.
2. The title should not too long
A title starts with a capital letter and has no trailing dot. Just like the subject line in an email. The title should make sense when read in a list of commits. If the title is too long, it will be cut off. The limit of 72 characters is safe to all typical places where people will be reading it, such as in a terminal window or when browsing Github or Gitlab.
3. The commit message needs to summarize the change and explain why
The text should be long enough for anybody reviewing the commit to understand why it was made, and to be convinced that the change is good. Every commit must have a text body, even if it is very short. This forces the author to spend a few seconds to think about the change before committing
Note that the commit message is about the change itself and it should answer the question ‘why’. If you want to explain how a certain line of code works, simply use an inline comment next to the code itself. That way the documentation is in the correct context. The git commit description should have just a tiny bit of ‘what’ and ‘how’, and mostly focus on the ‘why’.
The commit body should be wrapped at 72 characters, just like the title. Proper use of empty lines and lists that are indented with a dash or star makes the body more readable.
Remember to use imperative format. Don’t write Fixed bug or Added feature. Instead write Fix bug or Add feature. The patch hasn’t added or fixed anything at the time you wrote it. Think about it like an order you give to the code base to start following. Also try to keep your text in the current tense and passive format. Don’t write This commit makes X but simply Make X. Don’t write I changed Y but just simply Change Y.
4. Use references when available
If your code change is related to a previous commit, mention the commit ID. In most software commit IDs will automatically become links. If the code change is related to something that was discussed or tracked elsewhere, please include the bug tracker ID or a URL to the discussion. However, the reference alone does not remove the need to write a git commit message. You cannot expect that somebody reading your commit has time or even access to open and read all references - use them only as pointers for more information.
The last of our commit examples as viewed in gitk, Gitlab and Github illustrates how a git commit automatically becomes a link:
5. Maintain correct authorship and copyright credits
The author name and timestamp are automatic if you configured your git correctly, so it should be a non-issue. If you neglect configuring git with your real name and email, you will be mudding the waters for anybody who later wants to verify something about authorship. In the worst case all your commits might be purged from the git repository due to unclear copyright.
Also keep in mind that if you commit code on behalf of somebody else, you must tell git that the author for a particular commit was somebody else and you only committed it. Read up on git commit –author for details.
The right tools makes git commits easy
Using a good tool to craft your git commits goes a long way in making the commit flawless.
My personal choice is git-citool, which is distributed together with git itself, so anybody can use it on any operating system. It does not use the native graphics of each operating system, but a cross-platform graphics library, which may look a bit ugly. It is however very easy and convenient to use, so I love it.
To make a new commit, simply run git citool
. It starts off empty and then you can select which files you want to stage, and write the git commit message in this box, and press commit. Super easy, and it is very clear what changes you are committing.
Don’t settle with bad commits - amend them
If you are not happy with your commit and want to edit it, in git terminology you want to amend, which is possible only for the topmost git commit that does not have any child commits yet. Run git-citool --amend
.
Here you can see a git commit that is really bad, so it really needs to be fixed. However, with git-citool it is easy and fast.
WIP commits: how to avoid postpone writing the perfect git commit message
Remember that you don’t have to make a perfect git commit right off the bat. Do it only once you know what you actually want to write in it. While still working on the code and saving intermediate version of it, I recommend using WIP commits where the title is simply WIP or if you already have some commit text draft, prefix the title with WIP:.
A polished commit message is always worth the effort
Someone lazy might say that while they agree with the principles, they don’t have time to follow them. To that I respond that doing things correctly from the onset actually saves time down the road.
-
If your git commits are good, the job of the reviewer will be much easier, they won’t waste time on just trying to understand your change, but they get it directly and can focus their energy on actually reviewing and spotting flaws from your code. If you avoid shipping a bug, you save a lot of work not having to debug, write a fix and ship a new release at all.
-
A great git commit is also useful even if it later turns out the commit had a bug, because whoever fixes that but will have a much easier time reading in the commit what the change was supposed to do, and understanding where it fell short, and then doing the same change in the correct way. This leads to bugs being fixed much faster and with less effort - and most often the person doing the fix is a future you who no longer remembers what the present you were thinking while making that commit, and the future you just have to stare at the commit until it makes sense.
-
One extra benefit of having a great commit message is that you don’t have to rewrite anything when it comes time to submit the commit for review. Every single code review system I have ever used will automatically use the commit title and message from as the review title and message if the review is a single commit review.
Now go and build great software!
Now you know how to make a good git commit message. If you are proud of your work and like doing things well, you will follow these guidelines.