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:
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 \
commit.template '~/.config/git/message.txt'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.wikimediaIn 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 ↓ ---------- /SUBJECTFor 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 <[email protected]>
# Cc: Example User <[email protected]>
# Co-Authored-by: Example User <[email protected]>
# Requested-by: Example User <[email protected]>
# Reported-by: Example User <[email protected]>
# Reviewed-by: Example User <[email protected]>
# Suggested-by: Example User <[email protected]>
# Tested-by: Example User <[email protected]>
# Thanks: Example User <[email protected]>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 RestStructureTestStop 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.
Random blog