People should try to compare the quality of the kernel git logs with some other projects, and cry themselves to sleep.
– Linus Torvalds
I’ll never remember your project’s commit guidelines.
Every project insists on something different:
- Conventional commits
- Problem/Solution format
- Gitmoji
- The twisty maze of trailers in the Linux Kernel
But git commit templates help. Commit templates provide a scaffold for commit messages, offering documentation where you need it: inside the editor where you’re writing your commit message.
What is a git commit template?
When you type git commit
, git pops open your text
editor1. Git can pre-fill your editor with a
commit template—it’s like a form you fill out.
Creating a commit template is simple.
- Create a plaintext file – mine lives at
~/.config/git/message.txt
- Tell git to use it:
git config --global \
'~/.config/git/message.txt' commit.template
My default template packs everything I know about writing a commit.
Project-specific templates with IncludeIf
The real magic of commit templates is you can have different templates for each project.
Different projects can use different templates with git’s
includeIf
configuration setting.2
Large projects, such as the Linux kernel, git, and MediaWiki, have their own commit guidelines.
For Wikimedia work, I stow git repos in
~/Projects/Wikimedia
and at the bottom of my global git
config (~/.config/git/config
) I have:
[includeIf "gitdir:~/Projects/Wikimedia/**"]
path = ~/.config/git/config.wikimedia
In config.wikimedia
, I point to my Wikimedia-specific
commit template. I also override other git config settings like my
user.email
or core.hooksPath
.
An example: my global template
My default commit template contains three sections:
- Subject – 50 characters or less, capitalized, no end punctuation.
- Body – Wrap at 72 characters with a blank line separating it from the subject.
- Trailers – Standard formats with a blank line separating them from the body.
In each section, I added pointers for both format3 and content.
For the header, the guidance is quick:
# 50ch. wide ----------------------------- SUBJECT
# |
# "If applied, this commit will..." |
# |
# Change / Add / Fix |
# Remove / Update / Document |
# |
# ------- ↓ LEAVE BLANK LINE ↓ ---------- /SUBJECT
For the body, I remind myself to answer basic questions:
# 72ch. wide ------------------------------------------------------ BODY
# |
# - Why should this change be made? |
# - What problem are you solving? |
# - Why this solution? |
# - What's wrong with the current code? |
# - Are there other ways to do it? |
# - How can the reviewer confirm it works? |
# |
And that’s it, except for git trailers.
The twisty maze of git trailers
My template has a section for trailers used by the projects I work on.
# TRAILERS |
# -------- |
# (optional) Uncomment as needed. |
# Leave a blank line before the trailers. |
# |
# Bug: #xxxx
# Acked-by: Example User <user@example.com>
# Cc: Example User <user@example.com>
# Co-Authored-by: Example User <user@example.com>
# Requested-by: Example User <user@example.com>
# Reported-by: Example User <user@example.com>
# Reviewed-by: Example User <user@example.com>
# Suggested-by: Example User <user@example.com>
# Tested-by: Example User <user@example.com>
# Thanks: Example User <user@example.com>
These trailers serve as useful breadcrumbs of documentation. Git can parse them using standard commands.
For example, if I wanted a tab-separated list of commits and their
related tasks, I could find Bug
trailers using
git log
:
$ TAB=%x09
$ BUG_TRAILER='%(trailers:key=Bug,valueonly=true,separator=%x2C )'
$ SHORT_HASH=%h
$ SUBJ=%s
$ FORMAT="${SHORT_HASH}${TAB}${BUG_TRAILER}${TAB}${SUBJ}"
$ git log --topo-order --no-merges \
--format="$FORMAT"
d2b09deb12f T359762 Rewrite Kurdish (ku) Latin to Arabic converter
28123a6a262 T332865 tests: Remove non-static fallback in HookRunnerTestBase
4e919a307a4 T328919 tests: Remove unused argument from data provider in PageUpdaterTest
bedd0f685f9 objectcache: Improve `RESTBagOStuff::handleError()`
2182a0c4490 T393219 tests: Remove two data provider in RestStructureTest
Stop remembering commit message guidelines
Git commit templates free your brain from remembering what to write, allowing you to focus on the story you need to tell.
Save your brain for what it’s good at.