-
-
Save jalopez/e80206296fdf6e95902cf0ec0ef4ba5d to your computer and use it in GitHub Desktop.
A git hook to tag your commits with the JIRA issue ID. Requires a git client that runs the hook like Git Fork, Git Kraken, or anything TUI/CLI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# jira-prepare-commit-msg: Easy commit tagging for Jira | |
# | |
# https://gist.github.com/jeremy-w/818b2980f0d9768da83249458aa67678 | |
# | |
# If you name your branch to include the Jira issue key, | |
# this hook will automatically add the issue key to your commit messages. | |
# This makes it easy to trace work back to Jira, and it also means | |
# your commits show up in the Activity tab for that issue. | |
# | |
# To enable this hook: | |
# | |
# cd gitRepoParentDirectory | |
# ln -sf PATH/TO/jira-prepare-commit-msg */.git/hooks/prepare-commit-msg | |
# | |
# Execution context: | |
# | |
# - called by `git commit` in the git directory | |
# | |
# Parameters: | |
# | |
# - $1 is the filename holding the commit message. It already has stuff in it. | |
# - $2 is the commit message source (message, template, squash, commit, ...) | |
# - $3 is a commit ID - it's only present committing with -c, -C, or --amend | |
# | |
# The hook's purpose is to edit the commit | |
# message file, $1. If the hook fails with a non-zero status, | |
# the commit is aborted. | |
# | |
# Jeremy W. Sherman (@jeremy-w on GitHub) | |
# 2019-04-05 | |
# | |
# 2020-05-19: | |
# * NEW: Use jira.baseUrl config variable, if present, to include a link rather | |
# than just the issue ID in the commit messages. | |
# Example: git config --set jira.baseUrl https://YourCorp.atlassian.net/browse | |
# | |
# 2021-11-02: | |
# * FIXED: With newer git versions, the first commit on a branch was not | |
# picking up the branch name. | |
PROGNAME=$0 | |
function debug() { | |
# comment out next line to shut it up, uncomment to get some output | |
#echo "$PROGNAME: $*" >&2 | |
:; # empty functions aren't allowed, so here's a NOP | |
} | |
debug "Begun. Args: $*" | |
# Project Key format is configurable, but defaults to roughly this. | |
# https://confluence.atlassian.com/adminjiraserver/changing-the-project-key-format-938847081.html | |
ISSUE_REGEX="([A-Z]{1}[A-Z0-9_]{1,}-[0-9]{1,})" | |
if test "x$ISSUE_ID" = x; then | |
# Infer from beginning of branch name. | |
# While rev-parse is more accurate, it used to not work during rebase, but on | |
# recent versions, reports HEAD, while describe reports a hash alone. | |
# See: https://github.com/git/git/blob/041f5ea1cf987a4068ef5f39ba0a09be85952064/contrib/completion/git-prompt.sh#L446-L447 | |
branch=$(git rev-parse --abbrev-ref HEAD || git describe --contains --all --always) | |
debug "Issue ID unset; inferring from branch: $branch" | |
if [[ "$branch" =~ ^$ISSUE_REGEX ]]; then | |
ISSUE_ID=${BASH_REMATCH[1]} | |
debug "Inferred ISSUE_ID=$ISSUE_ID" | |
fi | |
fi | |
case "$2,$3" in | |
merge,) | |
debug "Commenting out those conflicts lines for ya." | |
/usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; | |
# The checks here are: | |
# - do we have an issue id to inject? | |
# - is there already one in the message body that's not commented out? | |
# (this avoids treating the ID in the branch name as an already-present ID) | |
*) if test \! "x$ISSUE_ID" = x && ! grep "^[^#]" "$1" | grep -E -q "$ISSUE_REGEX"; then | |
debug "Detected no issue ID in commit body. Adding it now as $ISSUE_ID." | |
# If we have URL info, then use that. | |
JIRA_ISSUE_URL_BASE=$(git config --get jira.baseUrl) | |
if test \! "x$JIRA_ISSUE_URL_BASE" = x; then | |
debug "Detected JIRA_ISSUE_URL_BASE of $JIRA_ISSUE_URL_BASE." | |
ISSUE_ID="$JIRA_ISSUE_URL_BASE/$ISSUE_ID" | |
debug "ISSUE_ID has been updated to $ISSUE_ID." | |
fi | |
# Place the issue ID after the commit message. | |
printf '\n\n%s\n' "$ISSUE_ID" >> "$1" | |
# If GIT_EDITOR is literally a colon character, there is no editor. | |
# Otherwise, append some comments to help the person editing the | |
# commit message. | |
if test \! "$GIT_EDITOR" = :; then | |
debug "Running interactive - adding some Smart Commit Syntax advice." | |
cat <<EOT >> "$1" | |
# You can log time, add comments, and trigger | |
# transitions using Smart Commit syntax. | |
# | |
# Example: | |
# JRA-123 JRA-234 JRA-345 #resolve #time 2d 5h #comment Task completed ahead of schedule | |
# | |
# See: <https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html> | |
EOT | |
fi | |
else | |
debug "Either no ISSUE_ID was detected, or there appears to be an issue ID already in the commit body." | |
debug " ISSUE_REGEX=$ISSUE_REGEX" | |
debug " ISSUE_ID=$ISSUE_ID" | |
debug " Commit body:\n$(cat "$1")" | |
fi;; | |
esac | |
debug "Done." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment