At work we have to add the Jira issue number to each pull request, branch and commit. This is to help Management with planning. Unfortunately for me, adding the Jira ID to each commit often broke with my existing workflow or I often just simply forgot to do add it. To remove this as an issue, how about a script to automate prepending the git commit message with the Jira ticket ID?
Git Hook Script
For the impatient, here’s the script.
First up, the script has some prerequisites and makes some assumptions:
- Requires Python 3
- Git branches follow the convention of using chore, feature, fix or hotfix, a
/followed by the Jira issue number (e.g. EX-100) and then the “branch name” e.g.
- Assumes there are valid branches that do not require this script to run e.g. at work release branches do not contain a Jira ticket ID.
With that out the way, let’s walk through the script and see what it does.
The shebang is important because we need to make sure this script executes using Python 3. Per the Python docs, “a good choice is usually
Next is a docstring to remind myself several months later what this script does. Then the imports required for the script. All imports are from the standard library so no need to pip install anything.
commit_msg_filepath is a system argument passed into the script. We use this later on, opening it as a file to write the commit message.
We find the branch name by using
From the Python docs:
Run command with arguments and return its output. By default, this function will return the data as encoded bytes.
It runs the git command
git symbolic-ref --short HEAD and the return is decoded to a string and stripped of whitespace.
The regex pattern for the git branch naming convention is declared as the
regex variable. This allows the script to extract the Jira ID. This script is lenient so if there is no match, it assumes there is a valid reason for the branch not having a Jira ID. If the regex has a match we enter the
if block. This is the code which amends the commit message.
The Jira issue number is group 2 in the
match regex. It opens the commit message as a file and reads in the contents of the file.
seek() is an interesting one. If writing a commit message in vim then
seek(0, 0) places the Jira ID as the first part of the commit message placeholder. Comment out
seek(0, 0) and you’ll see the Jira ID half way down in the git commit message verbiage yet it will still get written as the first part of the commit message. That’s because the final line writes the actually git commit message e.g. after you type it, save and exit Vim the message gets written as
[EX-100] example commit message.
Using the script
Finally, to make this script work there are two options.
Option one is to add to a single repo or to each repo you want this script to run. This wasn’t an option for me as we have many micro-services which I might work on and didn’t want to add the script to each repo.
Option two is to point global git config to a directory of your git hooks. This is what I went for and here’s how to do it.
Global Git Hooks
Save the script in a directory where you keep or plan to keep all your global git hooks. Make sure the script is executable
chmod +x prepare-commit-msg.
Then run this to point the global hooks to your directory:
cat .gitconfig to check the output:
│ File: .gitconfig ───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ [user] 2 │ name = Sam Atkins ... 5 │ [core] 6 │ hooksPath = /path-to/git_hooks
Here’s a link to the script on Github. Thanks for reading.