Prepending Your Git Commit Messages with User Story IDs

Nick Lee
4 min readSep 30, 2016

--

Image Courtesy of git-scm.com

It’s always a good practice to prepend your commit messages with something meaningful. For example, it is often common when working with project management tools, such as Jira, to prepend your commits with the User Story ID that you’re are working on. It’s also pretty standard, especially if using tools like BitBucket and creating branches from Jira, for your feature branch name to be the User Story ID plus title of the task/story. Wouldn’t it be great if you could append the ID from Jira to your BitBucket commits (and get the benefits of Smart Commits) without having to constantly memorise ticket numbers, or repeatedly run git branch to check the ticket number and branch name? Fear not, Git Hooks to the rescue.

Note: All teams have different standards and practices (or at least should have!) for writing commit messages so achieving a one size fits all commit message formatter is difficult, but the code in this tutorial can be very easily adapted to match your own style.

Let’s start off by looking at a basic commit message. A fairly common style is along the lines of

ABC-123 — a succinct description of work completed

where ABC-123 is the ticket/story ID in your project management platform (e.g. Jira). This is a simple format and has the added bonus of enabling linking commits in BitBucket with stories in Jira via Smart Commits. Our goal in this tutorial is to prepend commits with this ticket number automatically.

A good practice when working with agile and feature branches is to include the ticket number in the feature branch name as it’s good for traceability. If you’re using Jira to create your feature branches, you can create branches from the UI of the ticket and it will automatically have the ticket number prepended to the branch name. For this tutorial, we’ll assume this best practice is being followed. Therefore, if our branch was named “ABC-123-some-nice-feature”, we want to extract the ABC-123 segment and either prepend or append it to our commit message. This is where Git Hooks come in. Git Hooks are simply a way to trigger custom scripts when certain Version Control System (VCS) events occur and they can be found in the .git/hooks directory of your git based project.

Step 1: Create the hook file

Open up the .git/hooks directory of your project and you’ll see a handful of sample hook files for various VCS events. For our goal, we want to change the prepare-commit-msg.sample script which as the name suggests, is triggered when you make a git commit and prepare the commit message. Open this file with your favourite command-line text editor and delete all the commented out boilerplate code in there.

Step 2: Add the code to be triggered on commit

Copy and paste the following script in it’s place and then rename the file to prepare-commit-msg (i.e. remove the .sample).

#!/bin/bash
# Include any branches for which you wish to disable this script
if [ -z "$BRANCHES_TO_SKIP" ]; then
BRANCHES_TO_SKIP=(master develop staging test)
fi
# Get the current branch name and check if it is excluded
BRANCH_NAME=$(git symbolic-ref --short HEAD)
BRANCH_EXCLUDED=$(printf "%s\n" "${BRANCHES_TO_SKIP[@]}" | grep -c "^$BRANCH_NAME$")
# Trim it down to get the parts we're interested in
TRIMMED=$(echo $BRANCH_NAME | sed -e 's:^\([^-]*-[^-]*\)-.*:\1:' -e \
'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/')
# If it isn't excluded, preprend the trimmed branch identifier to the given message
if [ -n "$BRANCH_NAME" ] && ! [[ $BRANCH_EXCLUDED -eq 1 ]]; then
sed -i.bak -e "1s/^/$TRIMMED /" $1
fi

Now simply run git init to pick up the changes and try making a commit! You should see the ticket ID from your branch automatically prepended to your commit message.

Going Global

Manually adding this hook to all your projects is boring and not very DRY. Luckily, applying this globally is easily done by modifying your global git configuration to use a template:

Firstly, set up a git template directory using the git config command. In this example we’re using the .git-templates folder we’ve created in our home directory:

git config --global init.templatedir '~/.git-templates'

Then create the hooks directory for global hooks in your template folder:

mkdir -p ~/.git-templates/hooks

Afterwards, copy your hooks into this newly created directory and ensure permissions are correctly set on the file

chmod a+x ~/.git-templates/hooks/prepare-commit-msg

Done! Now whenever you run git commit, it will prepend the first segments of the branch to the commit message! For existing projects, you just need to reinit the git directory (don’t worry, it won’t break anything!) by running the following in the project root directory:

git init

--

--

Nick Lee

Interested in the classic mix of coding, startups, the economy, food and languages