Here are some guidelines on how to best structure and write a commit message, especially if you are using GitHub to host your git repository.
WARNING: This is a highly opinionated article and could cause some developers to lose their minds. I do not claim responsibility for all lost minds caused as a result of reading this article.
- Commit anatomy
- Subject line less than or equal to 72 characters in length
- Body line length limited to 80 characters
- Use sentence case for commit subject line with no period
- Use present tense imperative for the subject line and present tense for body text
- Use the footer to reference related issues
- Using VSCode to write commit messages
- Related tools
- Final note
- Related resources
Commit anatomy
Before going over the guidelines, it's best to review the anatomy of a commit message.
A commit message is comprised of a subject, body, and footer, with both the body and footer being optional. The subject is a single line that best sums up the changes made in the commit. The body text is used to provide more details regarding the changes made in the commit. The footer text is found immediately below the body and is a place to reference issues related to the commit changes. The body is separated by the subject by an empty line and similarly, the footer is separated from the body by an empty line.
Example commit message
1Add end-to-end test to shopping cart page23This adds several tests to the shopping cart page to catch potential regressions4introduced to the payment flow by the addition of new features.56The following functionality is tested:7- Adding multiple items to the cart8- Removing items from the cart9- Adding discount code to the cart10- Sending the user to payment details page when pressing the payment button1112Issue #123
Subject line less than or equal to 72 characters in length
To prevent a commit message's subject to be cut off in GitHub, make sure to limit the character length to 72 characters. This character limit is irrespective of the character width (i.e. even if an "I" character takes up less horizontal space than a "W" character in the GitHub UI, you will not be able to display more than 72 "I" characters).
Body line length limited to 80 characters
The line length for the body text of a commit message should be constrained to 80 characters. Regardless of if you manually wrap the body line length to 80 characters or not, the body text will appear as wrapped as 80 characters in the GitHub UI. However, limiting the line length to 80 characters makes commit messages more readable when trying to read them in the command line (such as when executing the command git log
).
The reason why having text span a large line length makes things less readable is because when reading multiple lines of text, your eyes need to be able to jump from the end of one line of text to the beginning of the next line of text. Having a longer line length makes this visual jump more difficult. This is easily illustrated by trying to read text that has a long line-length and a very small line-height (decreased line-height exacerbates this issue).
The only issue I see with wrapping body messages at 80 characters is that when you open a new pull request on GitHub and the pull request only has a single commit (which is a majority of my pull requests), GitHub will populate the pull request description with the text from the commit message body. With the text wrapped at 80 characters, there will be some whitespace in the pull request description. If you did not limit the commit body line length to 80 characters, then the default pull request description will fill the full space of the pull request description. Yes, you can simply remove this whitespace manually in the pull request description, but it's slightly annoying.
Use sentence case for commit subject line with no period
Use sentence case (without an ending period) for the commit subject line. This makes the subject read like the header for an article section. The commit body text should be punctuated and cased as you would expect from any normal paragraph of text (i.e. sentence case with periods).
Example
1Fix the lag while typing in the search bar23Now the logic for filtering the search results is debounced which gets rid of4the noticeable lag that appeared while typing in the search bar.
Use present tense imperative for the subject line and present tense for body text
The present imperative should be used for the subject line of commit messages. This is what has been standardized by git itself. For example, when merging one branch into another, git will search a commit message in the form of Merge branch 'branch-name'.
For a good discussion diving into the pros and cons of present vs past tense, see this stack overflow post.
Use the footer to reference related issues
The footer is the perfect place to reference issues that are affected by changes made in the commit. For example, if using JIRA to manage your project tasks, then refer to any JIRA issues in the footer.
1Fix the lag while typing in the search bar23Now the logic for filtering the search results is debounced which gets rid of4the noticeable lag that appeared while typing in the search bar.56Issue ABC-1337
Decide on a format on how you want to list issues in the footer and stick with it. Also, GitHub has a feature that allows you to automatically create links from text that matches a specific pattern in a pull request description. Therefore, if creating a pull request that has a single commit, the pull request description will include the commit message footer and if it matches the format you've configured in the GitHub settings, it will generate a link for you automatically (e.g. a link pointing the JIRA issue) 🎉.
Using VSCode to write commit messages
Most times I write my commit messages from the command line, but if I expect to write a long commit message, I'll usually do so in VSCode.
You can set VSCode as your default git editor by first installing the VSCode command-line interface and then execute the following command in your shell:
1git config --global core.editor "code --wait"
With VSCode set as your default git editor, whenever you execute git commit
, VSCode will open up for you to type in your commit message. The commit message is saved once you've closed the VSCode tab (can be done with ⌘ + w
). What is especially nice about this is that you can configure VSCode to set vertical rulers that can act as guides for the line length limits you wish to follow:
To set these rulers, just add the following to the VSCode global settings.json
file:
1"[git-commit]": {2 "editor.rulers": [72, 80]3}
Related tools
It's worth mentioning that there are some great tools out there related to commit guidelines and enforcing commit message rules.
Conventional Commits
Conventional Commits is a commit convention that is useful for describing how commit changes are related to the semantic version of an app as well as enable for some automated tooling that can leverage this specific commit convention. These types of commits take the following form:
1feat(home): add signup link to home page
1fix(signup): allow signup button to be clicked
This is a very popular commit standard that is followed, but unless you want to do some things like automatically generate changelogs or automatically bump semantic version numbers, this convention is probably overkill.
Commitlint
Commitlint is a tool to help enforce commit rules, such as line lengths, required empty lines between subject/body/footer, and more.
Final note
Keep in mind that a lot of the above is based on personal preference and you may want to use another convention when writing your commit messages. The most important thing that should be maintained, no matter what your preference may be, is consistency.