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 withgit 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 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:
# ----------------------------------------------------------
# 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:
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
.
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.
If you enjoyed this...
- ☕ Buy me a coffee to fuel my work
- See more of my configurations in my dotfiles
- Check out larger projects I’ve done in my portfolio
- Catch up with me on Twitter and LinkedIn.
Top comments (19)
Thanks for letting me know about this. I use git here and there and like the feature of template.
git config --global core.editor=nvim +14 -c 'startinsert' didn't work for me
I use arch, not sure if that's the reason, but for anyone having trouble with this.
My fix
git config --global core.editor 'vim +14 +startinsert'
cheers
Thanks for pointing this out, @haxnet . I've edited the article to include Neovim and Vim configurations, with links to more info!
Conventional Commits node package also does this for you but gives you a nice interactive cli asking you to choose / enter descriptions etc.
Thanks for this! It seems really slick. For anyone else interested, the project is called commitlint.
Can I suggest updating your example to match the style that is actually recommended on Conventional Commits site which you linked to.
Remove the brackets. Brackets are for scope.
Based on the link, if you were working on adding a language to the docs, you could add scope.
I think the scope is also useful for module. For example if you have
foo
andbar
insrc
directory, you would dofeat(foo)
to show the commits are scoped to thefoo
module.The scope can be whatever you want but the advice is your team needs to agree on it and stick to it.
Thanks for mentioning this. When I originally started using the convention, I didn't use the scope/module designator, since for many smaller projects it can be overkill. I just kept the parentheses around the type for aesthetics, but I see how that could be confusing for someone adopting the conventional method (and/or make the template incompatible with other conventional commit tools). I've updated the article to include these changes, and also added more info on structuring a commit message in my git configuration.
Cheers!
That linked page looks good.
That's a lot of dotfiles. Here are just a few of mine github.com/MichaelCurrin/dotfiles
Happy to help :)
Also you could turn your help message into a shell alias or a bookmarked page / gist so you can read it anytime without committing.
Something useful to add to your available type is
chore
. Such as deleting or renaming a file. Or changing a config like.gitignore
which relates more to the repo itself than your application's build flow.I started using
build
for only build-related configs - like apackage.json
or lint config file.I actually had already been using
chore
, but forgot to add it here! The article's been updated to include it. Thanks for mentioning it!You're welcome.
I'd appreciate if you have a look at my extension which doesn't let you choose a semantic message, it writes one for you.
github.com/MichaelCurrin/auto-comm...
There is also a nice vscode extension for conventional commits
Nice, thanks for sharing!
Just a minor typo: the git-config to set line 14 on vim should say
core.editor
instead ofcore-editor
.Thanks for catching that! It’s been edited and updated. Cheers!
Thank you for sharing
Thanks, really useful.
You may want to add that the comment character is configurable. In my case is ; so I modified the template accordingly.
Thanks! I've edited to include info on configuring the comment character. From git's documentation, both the
#
and;
characters are valid by default, but in case anyone wants theirs to be "🤫" or something, there is info on how to set it now!This is great 😎. I was thinking if i was able to do such a think. It is very useful for dev teams working with git - issues - branches.
Thanks for sharing Timothy.
I like the idea of creating a commit message template :). Might end up proposing this to the teams at my company!