I am trying to atomatize my git commits with bash functions so that they add a text before each commit if they detect that they are on a branch with a jira ticket.
For example I am working on a new issue and the branch is called bugfix/MR2-71-sidebar-modification where MR2-71 is the jira ticket number. I would like to find a general way to find as many cases as possible.
The bash functions I have are as follows
function getIssueName() {
local string="$(git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')"
# Extract the issue name from the branch name with regex without perl
# For example extract MR2-16 of the string feature/MR2-16-requests-list
# string variable will be feature/MR2-16-requests-list
# issueName variable will be MR2-123 only
local issueName="$(echo "$string" | sed -e 's/feature\/\(.*\)-.*/\1/' -e 's/bugfix\/\(.*\)-.*/\1/' -e 's/hotfix\/\(.*\)-.*/\1/' -e 's/release\/\(.*\)-.*/\1/' -e 's/\(.*\)-.*/\1/')"
# if issueName is empty or equal to string then return empty
if [ -z "$issueName" ] || [ "$issueName" = "$string" ]; then
echo ""
else
echo "$issueName"
fi
}
but issueName variable does not seem to have the ticket number correctly, as it sometimes brings extra string. for example MR2-71-sidebar-mod or MR2-75-table
Example content of the string variable (one for each line):
bugfix/MR2-38-refactor-routes-for-requests-list
bugfix/MR2-39-default-sorting-order-in-requests-list
feature/MR2-17-feature-clients-list
feature/MR2-34-laravel-9-upgrade
Example of the result that the function getIssueName should return (one for each line):
MR2-38
MR2-39
MR2-17
MR2-34
Any idea how to extract the issue number and make the function work in any case?
For example something like [aA-zZZ]-[0-9] (sorry I know almost nothing about regex)
I took a slightly different approach, find all jira tickets between two tags
https://gist.github.com/phillpafford/6081ee928762b1200722af499dab0418
#!/usr/bin/env bash
set -e
## https://confluence.atlassian.com/adminjiraserver/configuring-jira-application-options-938847824.html
## Project Key Length: Default: 10
JIRA_REGEX='[A-Z]{2,10}-[0-9]{1,7}'
JIRA_TICKET=()
# Set the tags
TAG_LATEST=$(git tag --sort=taggerdate | tail -1)
TAG_PREVIOUS=$(git tag --sort=taggerdate | tail -2 | head -n 1)
echo "TAG_LATEST: $TAG_LATEST"
echo "TAG_PREVIOUS: $TAG_PREVIOUS"
# Print the commits between the two tags
GIT_LOG=$(git log --pretty=format:%s $TAG_LATEST...$TAG_PREVIOUS)
while IFS= read -r line; do
## check for jira ticket regex in comment message
if [[ "$line" =~ $JIRA_REGEX ]]; then
## match found
if [[ ${BASH_REMATCH[0]} ]]; then
## push to array
JIRA_MATCH="${BASH_REMATCH[0]}"
JIRA_TICKET+=($JIRA_MATCH)
fi
fi
done <<< "$GIT_LOG"
## unique JIRA_TICKET
JIRA_TICKET=($(for jt in "${JIRA_TICKET[@]}"; do echo "${jt}"; done | sort -u))
FOUND_JIRA_TICKET=${#JIRA_TICKET[@]}
echo "FOUND_JIRA_TICKET: $FOUND_JIRA_TICKET"
if [ $FOUND_JIRA_TICKET -gt 0 ]; then
echo "Jira Tickets"
printf '%s\n' "${JIRA_TICKET[@]}"
fi
## end
Hey Here is my pre-commit git hook to do exactly that, it's not perfect by any means, as it appends the ticket id in '[]' at the end of every line this isn't an issue for me as most of my commits are one-liners and anything more complex can be ran with the --skip-validation hooks
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 " s/$/ $PREFIX/" $1
fi
fi
and an assortment of references that helped me along the way
# - 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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
#!/usr/bin/env bash
# based on Hamish's super helpful script, some small tweaks
# 1. pass "1" to sed to only edit the first line
# 2. try sed with and without the .back, for osx or linux
# 3. strip comments before looking for jira number, as branch always appears in comments for me
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
JIRA_PATTERN='[A-Z]{3,4}-[0-9]{2,5}'
[[ $BRANCH_NAME =~ $JIRA_PATTERN ]]
JIRA=${BASH_REMATCH[0]}
JIRA_IN_COMMIT=$(grep "$JIRA" $1 | grep -v ^# -c)
# Ensure JIRA exists in BRANCH_NAME and is not already present in the commit message
if [[ -n "$JIRA" ]] && ! [[ $JIRA_IN_COMMIT -ge 1 ]]; then
sed -i "1 s/^/$JIRA: \n/" $1 2> /dev/null || sed -i .bak "1 s/$/ $JIRA/" $1
fi
fi
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.