The commit hook is executed when you close the commit message editor. It can, among other things, be used to manipulate the commit message or review the commit message by machine to check whether it has a specific format.
In this recipe, we will be manipulating and checking the content of a commit message.
To start this exercise, we just need to create a branch and check it out. We need to disable the current prepare-commit-msg hook; we can do this by simply renaming it. Now, we can start working on the commit-msg hook by using the following command:
git checkout -b commit-msg-example Switched to a new branch 'commit-msg-example' $ mv .git/hooks/prepare-commit-msg .git/hooks/prepare-commit-msg.example
What we want to do in the first example is to check whether the defect information is correct. There is no need to release a commit that refers to a defect that does not exist:
$ cp .git/hooks/commit-msg.sample .git/hooks/commit-msg
#!/bin/bash echo "you are not allowed to commit" exit 1
$ echo "Frogs, scallops, and coco shell" >> fishtank.txt $ git add fishtank.txt $ git commit
you are not allowed to commit
message, and if you check with git log -1
, you will see that you don't have a commit with the message you just used, as follows:you are not allowed to commit $ git log -1 commit 70cad5f7a2c3f6a8a4781da9c7bb21b87886b462 Author: Rasmus Voss <[email protected]> Date: Thu Mar 6 08:25:21 2014 +0100 somebody keeps erasing my changes. You have a dirty workarea are you sure you wish to commit ?
#!/bin/bash JIRA_ID=$(cat $1 | grep jenkins | sed 's/jenkins //g') ISSUE_INFO=$(curl https://issues.jenkins-ci.org/browse/JENKINS-${JIRA_ID} | grep "The issue you are trying to view does not exist.") if [ "${ISSUE_INFO}" ]; then echo "Jenkins issue ${JIRA_ID} does not exist" echo "Please try again" exit 1 else TITLE=$(curl https://issues.jenkins-ci.org/browse/JENKINS-$JIRA_ID} | grep -E "<title>.*</title>") echo "Jenkins issue ${JIRA_ID}" echo "${TITLE}" exit 0 fi
The issue you are trying to view does not exist
; if we find this text, we know that the ID does not exist. Now we should create a commit and see what happens if we put in the wrong ID, jenkins 384895
, or an ID that exists as jenkins 3157
. To check this, we will create a commit as follows:$ echo "more water" >> fishtank.txt $ git add fishtank.txt $ git commit
Feature cascading…
as a commit message subject. Then, in the body of the commit message, insert jenkins 384895
. This is the important part as the hook will use that number to look it up on the Jenkins issue tracker:Feature: Cascading... jenkins 384895
Jenkins issue 384895 does not exist Please try again
git status
whether the change has not been committed:$ git status On branch commit-msg-example Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: fishtank.txt
$ git commit
Feature: Cascading... jenkins 3157
<title>[#JENKINS-3157] Feature request: cascading project settings - Jenkins JIRA</title> [commit-msg-example 3d39ca3] Feature: Cascading... 1 file changed, 2 insertions(+)
else
clause in the script:TITLE=$(curl https://issues.jenkins-ci.org/browse/JENKINS-${JIRA_ID} | grep -E "<title>.*</title>") TITLE=$(echo ${TITLE} | sed 's/^<title>//' |sed 's/</title>$//') echo "${TITLE}" >> $1 echo "Jenkins issue ${JIRA_ID}" echo "${TITLE}" exit 0
$ echo "Shrimps and mosquitos" >> fishtank.txt $ git add fishtank.txt $ git commit After saving the commit message editor you will get an output similar like this. Jenkins issue 3157 [#JENKINS-3157] Feat [commit-msg-example 6fa2cb4] More cascading 1 file changed, 1 insertion(+)
git log -1
again:$ git log -1 commit 6fa2cb47989e12b05cd2689aa92244cb244426fc Author: Rasmus Voss <[email protected]> Date: Thu Mar 6 09:46:18 2014 +0100 More cascading jenkins 3157 [#JENKINS-3157] Feature request: cascading project settings - Jenkins JIRA
As expected, we have the information at the end of the commit. In these examples, we are just discarding the commit message if the JIRA ID does not exist; this is a little harsh on the developer. So, you can combine this with the prepare-commit-msg hook. So, if commit-msg halts the commit process, then save the message temporarily so that the prepare-commit-msg hook can use that message when the developer tries again.