In this example we are going to use the GIT commit-msg hook to amend the original message. It will ask user to amend the original message if it doesn't meet the requirements otherwise it will continue as if nothing has happened. The user is not forced to change the message.


Logic


When we use project management tools (e.g. JIRA, Pivotal, Assembla etc.), the tasks we work on often have identification numbers. Sometimes it is good to use these numbers as part of our GIT branch names and commit messages for easy identification purposes. This example encourages users to add task numbers to comments as well as the GIT branch names. There are some rules so you should read the comments because they don't apply to all commit messages and branches.


commit-msg


Create commit-msg file with the content below.


vagrant@other:~/git$ nano .git/hooks/commit-msg

#!/bin/bash

currentBranch=$(git rev-parse --abbrev-ref HEAD)

# Is branch "feature" or "hotfix"
if [[ $currentBranch == ticket/* ]] || [[ $currentBranch == hotfix/* ]] ;
then
error=false
ticketType=$(echo $currentBranch | cut -d'/' -f 1)
ticketNumber=$(echo $currentBranch | cut -d'/' -f 2 | cut -d'-' -f 1)
currentCommitMessage=`echo "$(cat $1)" | head -1`

# If no commit message given then abort
if [ -z "$currentCommitMessage" ] ;
then
printf "\n\033[0;31mAborting the commit due to empty commit message.\033[0m\n\n"
exit 1;
fi

# If the ticket/branch is "hotfix" and doesn't start with a number then no more checks
if [[ $ticketType == hotfix ]] && ! [[ $ticketNumber =~ ^[0-9]+$ ]] ;
then
exit 0;
fi

# If the ticket/branch doesn't start with a number then set error
if ! [[ $ticketNumber =~ ^[0-9]+$ ]] ;
then
printf "\n\033[0;31mAborting the commit due to invalid ticket number.\033[0m\n\n"
exit 1;
fi

# If the commit message doesn't start with a number then set error
if [[ $currentCommitMessage != "${ticketNumber} - "* ]] ;
then
error=true
fi

# If error is set
if [ $error == true ] ;
then
printf "\n\033[0;33m[GIT POLICY]\033[0m Commit messages for 'ticket' and 'hotfix' branches must be prefixed with ticket numbers if exists.\n\n"

# Allow cursor hanging
exec < /dev/tty

# Start infinite loop to wait for user's input
while true;
do
proposedCommitMessage="${ticketNumber} - ${currentCommitMessage}"

printf "CURRENT : ${currentCommitMessage}\n"
printf "PROPOSED : ${proposedCommitMessage}\n\n"
read -p "Would you like me to amend the 'current' message as 'proposed' one as shown above? (y/n) " amend

# If user accepts the offer above (message amendment or not)
if [[ $amend =~ ^[Yy]$ ]] ;
then
$(echo $proposedCommitMessage > $1)
printf "\n\033[0;32mThe message has been amended.\033[0m\n\n"
else
printf "\n\033[0;31mThe message has been left intact.\033[0m\n\n"
fi

break
done
fi
fi

Make the file executable by running $ chmod +x .git/hooks/commit-msg command.


Tests


feature/testing


This will not prompt user because it is neither a "ticket" nor a "hotfix". It is a "feature" branch.


vagrant@other:~/git$ git commit -m 'Commiting'
[feature/testing 660d36d] Commiting
1 file changed, 1 insertion(+)

ticket/testing


This will force user to add the ticket number to branch name because it is a "ticket".


vagrant@other:~/git$ git commit -m 'Commiting'

Aborting the commit due to invalid ticket number.

ticket/123-testing


This will ask user if he wishes to prefix his commit message with the ticket number 123 because he originally didn't add it to the message.


vagrant@other:~/git$ git commit -m 'Commiting'

[GIT POLICY] Commit messages for 'ticket' and 'hotfix' branches must be prefixed with ticket numbers if exists.

CURRENT : Commiting
PROPOSED : 123 - Commiting

Would you like me to amend the 'current' message as 'proposed' one as shown above? (y/n) y

The message has been amended.

[ticket/123-testing b4e4b27] 123 - Commiting
1 file changed, 1 insertion(+)

ticket/123-testing


This will not ask user if he wishes to prefix his commit message with the ticket number 123 because he already added it to the message.


vagrant@other:~/git$ git commit -m '123 - Commiting'
[ticket/123-testing 9803ed3] 123 - Commiting
1 file changed, 1 insertion(+)

hotfix/testing


This will not ask user if he wishes to prefix his commit message with the ticket number because the branch is a "hotfix" and doesn't have a ticket number anyway.


vagrant@other:~/git$ git commit -m 'Commiting'
[hotfix/testing ebe8af1] Commiting
1 file changed, 1 insertion(+)

hotfix/123-testing


This will ask user if he wishes to prefix his commit message with the ticket number 123 because he originally didn't add it to the message.


vagrant@other:~/git$ git commit -m 'Commiting'

[GIT POLICY] Commit messages for 'ticket' and 'hotfix' branches must be prefixed with ticket numbers if exists.

CURRENT : Commiting
PROPOSED : 123 - Commiting

Would you like me to amend the 'current' message as 'proposed' one as shown above? (y/n) y

The message has been amended.

[hotfix/123-testing 11d58a8] 123 - Commiting
1 file changed, 1 insertion(+)