Keeping Git Commit Messages Consistent with a Custom Template
Tags: git, github, productivity, tutorial
Published: 2021-01-10 17:38:33

<img src="https://imgs.xkcd.com/comics/git_commit.png" alt="XKCD comic 1296 displaying increasingly less informative git commit messages over the course of a project" />
<figcaption>xkcd on git commit messages</figcaption>

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](https://www.conventionalcommits.org/en/v1.0.0-beta.2/), 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.](https://chris.beams.io/posts/git-commit/)

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.

```sh
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](https://git-scm.com/docs/git-config#_syntax), 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:

```git
# ----------------------------------------------------------
# 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:

```sh
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 enter `git 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:

```git
# ----------------------------------------------------------
# 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 detailed 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:

```git
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](https://github.com/timmybytes/dotfiles/blob/main/git/README.md). 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:

```sh
# 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 editor with git here](https://stackoverflow.com/questions/2596805/how-do-i-make-git-use-the-editor-of-my-choice-for-commits)

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. 

---

![timmybytes banner](https://raw.githubusercontent.com/timmybytes/timmybytes-website/main/img/timmybytes-header.png)

If you enjoyed this...
* ☕ [Buy me a coffee to fuel my work](https://ko-fi.com/timmybytes)
* See more of my configurations in my [dotfiles](https://github.com/timmybytes/dotfiles)
* Check out larger projects I’ve done in my [portfolio](https://timmybytes.com)
* Catch up with me on [Twitter](https://twitter.com/timmybytes) and [LinkedIn](https://www.linkedin.com/in/timmybytes).