Updated on 2021-06-02: An extended version of the script is described here: Checkout PR script.
We have a rule on the project where every commit (and PR) should include the ticket number that it’s related to; by convention, it goes at the beginning of the commit message’s title, e.g. “US123: Display relative date when it’s closer than one day”. The rule also extends to the branch name, e.g.
userStory/US123_display_relative_date. This makes it convenient to automate the insertion of the ticket number into the commit message, which is possible to do locally using
I came up with this
prepare-commit-msg hook a few years ago and have been improving it slightly over the years:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
The script should be put into your working directory’s
.git/hooks/prepare-commit-msg. It will run automatically for every commit before the user edits the commit message.
What it does is:
- stores the filepath to the file, which the user then will edit to write the commit message, in
COMMIT_MSG_FILE— this is a more semantic name then
- gets the current branch name into the
- extracts a ticket number from the branch name with
- and if there is one and the first line of the commit message file doesn’t start with it yet (which may happen e.g. during
git rebase), it prepends the number to the first line. It was easier to implement this regex with
sed, because the latter supports addresses (to update the first line only) but not negative lookahead.
Also, the script doesn’t add the ticket number if the commit message starts with
fixup!, which is a very convenient feature of
git. If you want to edit the latest commit, you can
git commit --amend, but if you want to edit e.g. the third commit back, you can do your changes,
git commit --fixup=@~3 to record that they should be integrated into that commit (this will create a new commit with the message
fixup! 123abcd), then
git rebase -i --autosquash master to rebase your branch onto your base branch and automatically merge the fix into the original commit. See more for example here: https://www.mikulskibartosz.name/git-fixup-explained/.
As for the ticket names, you may have a uniform name for all kinds of tickets in your project, e.g.
PROJ123, or a different prefix based on the ticket type, such as
US123 for user stories,
DE234 for bugs/defects,
TA345 for user stories’ tasks, etc. The script supports the latter case where it extracts one of the possible matches:
grep -Eo '(US|DE|TA|F)\d+', which can be
F followed by 1+ digits.
Given that I use it every working day dozens of times, the hook works very well in all cases that I’ve had: commit, amend, rebase, merge, fixup.
There is a more extended version of the hook that supports local PR branches. It’s based on my other script to check out those PRs, and I covered it in another blog post.
There are many other interesting things that can be done with
git hooks. For more information about them, run
man githooks or visit https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks or https://githooks.com/.