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.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.