Using Git hooks to add JIRA issue to commit message
A short and simple guide on what are git hooks and how we can use them to prepend a JIRA issue to the commit messages.
TL;DR
Create global hooks folder
ls ~/.git-hooks || mkdir ~/.git-hooks
- Copy the following script to
~/.git-hooks
directory, under the nameprepare-commit-msg
2. Edit the ExcludedBranches and IncludedOrigins according to your project’s requirements.
3. Set the script with execution permission and configure ~./git-hooks as the global git hooks folder
chmod a+x ~/.git-hooks/prepare-commit-msg
git config --global core.hooksPath '~/.git-hooks'
The outcome is a commit message for some commit message
should look like > [ISSUE-12] — some commit message
Git hooks
So, what are a git hooks ??
Hooks are programs you can place in a hooks directory to trigger actions at certain points in git’s execution.
simply saying hooks let you connect to the git execution in certain predefined points, and execute some action (script/software) that you create.
Types of hooks
The list of available hooks to use and their parameters can be found at git hooks.
Git hooks can be configure as either global or local.
- local — will exist in the repo itself and will be applied only for that specific git repository.
- global — will exist at a shared location on the workstation and will be applied to all git repos that are on this workstation.
Let's get started
For the editing of the commit message we will use prepare-commit-msg hook, which is triggered by a commit, and provides 3 parameters:
- Name of the file that contains the commit log message
- Source of the commit message(e.g: message, commit, template, merge, squash).
- The commit’s SHA1
Important note: A non-zero exit means a failure of the hook and aborts the commit. It should not be used as replacement for pre-commit hook. (aka avoid non-zero exit in this hook)
Creating our hook
in order to create a hook for a git repository we need to check if there is a hooks folder and if not, create one
ls .git/ | grep hooks/ || mkdir .git/hooks
Next, we need to create the hooks file and edit it: (the following command will create a file and open it in xcode)
touch .git/hooks/prepare-commit-msg && open -a xcode .git/hooks/prepare-commit-msg
once the file is created, copy the content of the script, and edit the ExcludedBranches and IncludedOrigins according to your project’s requirements.
In order for the script to run we need to make sure it executable permissions, to do so run: (adds executable permissions to all uses for the hook)
chmod a+x .git/hooks/prepare-commit-msg
What happens here?
we read the file from the provided parameters
messageFile = ARGV[0]
Then, we run the following checks before apply the change:
- Is the repo configured in the whitelisted git origins?(IncludedOrigins) - the idea is that we want to apply the hooks only for certain central repos that we work with (and not to private ones for example)
- Is the current head branch excluded?(ExcludedBranches)- is the branch that i am commiting to is in the list of excluded branches?
- Does the branch contains a JIRA issue?
- Does the commit message already contains a JIRA issue?
Then we apply the change by modifying the text however we like (in this case add the jira ticket prefix)and write the modified text back to the file.
modifiedText = "[#{match.to_s}] - #{text}"
File.write(messageFile, modifiedText)
Making the hook global
Say we don’t want this behaviour for all the of the repos from a certain origin (configurable in the script), and we do not want to set this script for every repo, as it is tedious, and the hooks folder cannot be tracked by git (more on that here), here comes in global git setting, which are applied to all repos on the workstation.
To get it going simply create a custom hooks directory, save the script we created (with the same naming) to the directory and configure it as the global hooks directory
ls ~/.git-hooks || mkdir ~/.git-hooks
Now, copy the script to the newly created `~/.git-hooks` folder and let’s configure the folder as the global git hooks folder, and provide the script with executable permissions
git config --global core.hooksPath '~/.git-hooks'
chmod a+x ~/.git-hooks/prepare-commit-msg
And that is it.