← Back to blog home

Keeping Git Commit Messages Consistent with a Custom Template

The ability to write consistent git commit messages is a skill that will serve both you and any team you’re working with well in the long run. If you often find yourself struggling to come up with a decent message format, or you’re unable to decipher what it was you were doing when looking back through old commits, this little fix might help. And the best part is it’s extremely easy to implement.

You can set a file to act as a commit message template through git’s global configuration. I tend to follow the conventional commits format, which makes it easy to decide how to format your messages, and keeps things organized across all your commits. Chris Beams also has a great article on this topic.

First, create a .txt file in a directory of your choice that will act as the template. I’ll assume you’re using the terminal for the process.

touch commit-conventions.txt

Open the .txt file with the editor of your choice. Git will ignore lines that begin with a # or ; by default, so we’ll use those to make a template of ignored lines that only you will see when you’re making commits.

Note: By default, git allows both # and ; as comment characters for configuration files, but you can set a character of your choice with git config --global core.commentChar '#', substituting # with your preferred character.

You can put whatever you want in your template, but here’s mine as an example:

# ----------------------------------------------------------
# Header - type(scope): Brief description
# ----------------------------------------------------------
# * feat A new feature - SemVar PATCH
# * fix A bug fix - SemVar MINOR
# * BREAKING CHANGE Breaking API change - SemVar MAJOR
# * docs Change to documentation only
# * style Change to style (whitespace, etc.)
# * refactor Change not related to a bug or feat
# * perf Change that affects performance
# * test Change that adds/modifies tests
# * build Change to build system
# * ci Change to CI pipeline/workflow
# * chore General tooling/config/min refactor
# ----------------------------------------------------------


# ----------------------------------------------------------
# Body - More description, if necessary
# ----------------------------------------------------------
# * Motivation behind changes, more detail into how
# functionality might be affected, etc.
# ----------------------------------------------------------


# ----------------------------------------------------------
# Footer - Associated issues, PRs, etc.
# ----------------------------------------------------------
# * Ex: Resolves Issue #207, see PR #15, etc.
# ----------------------------------------------------------


To add the template to your global git config is enter the following:

git config --global commit.template path/to/your/file.txt

Now whenever you’re making a commit, instead of the typical git commit -m "A brief commit message", just entergit commit to open your default editor with the template in place. You’ll automatically have a guide to choose conventions from to create a structured message. For example:

# ----------------------------------------------------------
# Header - type(scope): Brief description
# ----------------------------------------------------------
# * feat A new feature - SemVar PATCH
# * fix A bug fix - SemVar MINOR
# * BREAKING CHANGE Breaking API change - SemVar MAJOR
# * docs Change to documentation only
# * style Change to style (whitespace, etc.)
# * refactor Change not related to a bug or feat
# * perf Change that affects performance
# * test Change that adds/modifies tests
# * build Change to build system
# * ci Change to CI pipeline/workflow
# * chore General tooling/config/min refactor
# ----------------------------------------------------------
docs: Update README with contributing instructions

# ----------------------------------------------------------
# Body - More description, if necessary
# ----------------------------------------------------------
# * Motivation behind changes, more detail into how
# functionality might be affected, etc.
# ----------------------------------------------------------
Adds a CONTRIBUTING.md with PR best practices, code style
guide, and code of conduct for contributors.

# ----------------------------------------------------------
# Footer - Associated issues, PRs, etc.
# ----------------------------------------------------------
# * Ex: Resolves Issue #207, see PR #15, etc.
# ----------------------------------------------------------
Closes #9

The “header” of the commit message notes the type of the commit as docs and a brief description that does not exceed 60 characters to ensure readability (the commented lines are 60 characters long and act as guides for when to use a line break). The “body” optionally elaborates on the changes made, and the “footer” optionally notes any issue/PR the commit is related to. The final message will simply look like this:

docs: Update README with contributing instructions

Adds a CONTRIBUTING.md with PR best practices, code style
guide, and code of conduct for contributors.

Closes #9

For more specifics on the convention formatting or how it works with semantic versioning, see my git configuration. If it's too confusing or overly complex for your use cases, just simplify as needed.

If you use Vim or Neovim, and you want to speed up the process even more, you can add this to your git config:

# Neovim
git config --global core.editor=nvim +16 -c 'startinsert'

# Vim
git config --global core.editor "vim +16 +startinsert"

This sets the default editor to Neovim (or Vim), and places the cursor on line 16 in Insert Mode as soon the editor opens. Now whenever you’re committing, when you type git commit, Neovim opens the template, places your cursor, and accepts typing input immediately. Also note that you can still use git commit -m "Your message" exactly as you did before, but the configuration will default to the template setup when you just type git commit.

See more tips for configuring your git editor here.

Setting up this template has saved me countless time and frustration, and makes it so much easier to track my commits since all my repos use the same global commit format. You can get much more creative with git defaults and complex githooks, but this is a great way to solve a common problem for most developers.

← Back to blog home