Skip to content

Instantly share code, notes, and snippets.

@johncmunson
Last active September 17, 2024 15:43
Show Gist options
  • Save johncmunson/ca02a8027a923a7f4b2f662c67d6528c to your computer and use it in GitHub Desktop.
Save johncmunson/ca02a8027a923a7f4b2f662c67d6528c to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# Inspects branch name and checks if it contains a Jira ticket number (i.e. ABC-123).
# If yes, commit message will be automatically prepended with [ABC-123].
#
# Useful for looking through git history and relating a commit or group of commits
# back to a user story.
#
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
# Ensure BRANCH_NAME is not empty and is not in a detached HEAD state (i.e. rebase).
# SKIP_PREPARE_COMMIT_MSG may be used as an escape hatch to disable this hook,
# while still allowing other githooks to run.
if [ ! -z "$BRANCH_NAME" ] && [ "$BRANCH_NAME" != "HEAD" ] && [ "$SKIP_PREPARE_COMMIT_MSG" != 1 ]; then
PREFIX_PATTERN='[A-Z]{2,5}-[0-9]{1,4}'
[[ $BRANCH_NAME =~ $PREFIX_PATTERN ]]
PREFIX=${BASH_REMATCH[0]}
PREFIX_IN_COMMIT=$(grep -c "\[$PREFIX\]" $1)
# Ensure PREFIX exists in BRANCH_NAME and is not already present in the commit message
if [[ -n "$PREFIX" ]] && ! [[ $PREFIX_IN_COMMIT -ge 1 ]]; then
sed -i.bak -e "1s~^~[$PREFIX] ~" $1
fi
fi
#
# Resources:
# - https://gist.github.com/bartoszmajsak/1396344
# - https://stackoverflow.com/questions/34213120/find-branch-name-during-git-rebase
# - https://github.com/typicode/husky/issues/311#issuecomment-580237182
# - https://gmurphey.github.io/2013/02/02/ignoring-git-hooks-when-rebasing.html#.XkK1AhNKjOQ
# - https://mikemadisonweb.github.io/2018/12/18/git-hook-prepending-commit-message/
# - https://stackoverflow.com/questions/5894946/how-to-add-gits-branch-name-to-the-commit-message
# - http://blog.bartoszmajsak.com/blog/2012/11/07/lazy-developers-toolbox-number-1-prepend-git-commit-messages/
# - https://docs.npmjs.com/files/package.json#bin
# - https://www.deadcoderising.com/how-to-smoothly-develop-node-modules-locally-using-npm-link/
# - https://github.com/sindresorhus/execa
# - https://github.com/shelljs/shelljs
#
#
# Alternative method for finding the branch name
#
# Note that during a rebase, this will return something like
# (no branch, rebasing ABC-123-feature-x)
# instead of
# HEAD
#
# BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
#
#
# Also, don't forget to place this inside package.json if this is part of a node/npm project
#
# "husky": {
# "hooks": {
# "prepare-commit-msg": "./prepare-commit-msg.sh $HUSKY_GIT_PARAMS"
# }
# }
#
@cmackenzie1
Copy link

Nice script. I would suggest a minor change to the PREFIX_PATTERN. As it currently is, it only supports tickets that have a code of only 4 letters.

A more general regex would be as follows: https://regex101.com/r/o3ubPk/1

@johncmunson
Copy link
Author

johncmunson commented Feb 21, 2020

Thanks @cmackenzie1! I like where you're coming from, but I tested out your regex and it didn't seem to work when dropped into the bash script (even though it works as expected when testing on regex101.com).

It probably just needs a slight tweak to work in the context of bash, but my bash-fu isn't strong enough to get it right.

In the meantime, I think PREFIX_PATTERN='[A-Z]{2,5}-[0-9]{1,4}' is a slight improvement over what I had previously, PREFIX_PATTERN='[A-Z]{4}-[0-9]{3,4}', so that it works with a wider variety of Jira ticket formats.

@dmwelch
Copy link

dmwelch commented Feb 24, 2020

You can get really flexible and use PREFIX_PATTERN='[A-Z]{2+}-[0-9]{2+}' which I believe would allow strings like CHEMAPP-01` and "ABC-1111"

@johncmunson
Copy link
Author

johncmunson commented Mar 2, 2020

Nice, thanks @dmwelch. I took a crack this weekend at turning this into an npm package.

The general idea is...

  1. npm install prefix-commit
  2. Under the husky section in package.json... "prepare-commit-msg": "PATTERN='...' prefix-commit"

Husky is successfully running the installed script, but when it's run in this context I'm getting the following error when it reaches sed on line 43...

sed: -i may not be used with stdin

@cmackenzie1
Copy link

Nice, thanks @dmwelch. I took a crack this weekend at turning this into an npm package.

The general idea is...

  1. npm install prefix-commit
  2. Under the husky section in package.json... "prepare-commit-msg": "PATTERN='...' prefix-commit"

Husky is successfully running the installed script, but when it's run in this context I'm getting the following error when it reaches sed on line 43...

sed: -i may not be used with stdin

This is because husky is piping the message through stdin and not as a file. Take a look at https://github.com/bk201-/jira-prepare-commit-msg

@okankaraduman
Copy link

Hello @johncmunson , thank you for the amazing script. Can you give me an example of how to use SKIP_PREPARE_COMMIT_MSG?

@ddubrava
Copy link

Hi! Thank you for your script, there are some notes:

  1. the regex mentioned above doesn't work, you should use {2,} instead of {2+}. So use this [A-Z]{2,}-[0-9]{2,}`.
  2. this hook executes on a merge commit, so you need to add [ $2 != merge ].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment