10

I'm new to git and I want to be able to capture the commit message after a push to the origin/master and run a bash script (on the server) based on what the string contains.

For example, if my git commit message says: [email] my commit message

If the commit message contains [email] then do a specified action, otherwise, don't do it.

Here's a sample bash script I'm thinking of using in the post-receive hook:

#!/bin/bash

MESSAGE= #commit message variable?

if [[ "$MESSAGE" == *[email]* ]]; then
        echo "do action here"
else
        echo "do nothing"
fi

Basically all I need to know is what the variable name for the commit message is, to use in the above bash script? Also, I'm not sure if this is the right hook to do this or not.

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
James Nine
  • 2,548
  • 10
  • 36
  • 53

2 Answers2

29

I think I figured out the answer to my own question; the variable can be obtained using the git-log command:

git log -1 HEAD --pretty=format:%s

so, my script would be:

#!/bin/bash

MESSAGE=$(git log -1 HEAD --pretty=format:%s)

if [[ "$MESSAGE" == *\[email\]* ]]; then
        echo "do action here"
else
        echo "do nothing"
fi

I hope this might help anyone else who is searching for the answer.

James Nine
  • 2,548
  • 10
  • 36
  • 53
  • 1
    So this `[email]` markup is going to be permanently part of your commit message? – Cascabel Feb 02 '11 at 06:53
  • Other possible methods: use an environment variable to signal to the hook, so there's never anything in the commit message about it. Use an alias to make this easier. Or, if you want to write it in the message, detect the markup in a pre-commit hook so you can modify the message before the commit is recorded. (Either assume the commit will succeed and email right away, or store something for the post-commit hook to key on...) – Cascabel Feb 02 '11 at 07:00
  • Or are you really doing this post-receive, not post commit? Then you of course can't modify the commit message anymore. However, that means your solution doesn't work: a push doesn't just push one commit, it updates any number of refs, each of which could include any number of new commits. You should really look at the [example](http://git.kernel.org/?p=git/git.git;a=blob;f=contrib/hooks/post-receive-email;hb=HEAD) in git's contrib. It handles quite a lot, and you could modify it to only pay attention to commits that say `[email]`. – Cascabel Feb 02 '11 at 07:12
  • And finally, if you decide to implement your own, you will need to read the information [passed into the hook on stdin](http://www.kernel.org/pub/software/scm/git/docs/githooks.html#pre-receive) (it's the same as the pre-receive hook), and then for each ref, examine the commits from the old value to the new value, and take appropriate action for each. – Cascabel Feb 02 '11 at 07:13
  • @James Nine, If I have a multi-line commit message then you solution will not work as it will display only the first line of the commit message. git log -1 HEAD --pretty=format:%s The above command will display only the first line of the commit message. –  Feb 07 '12 at 14:01
1

You probably want a git hook for that

Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232
  • I'm already using the post-receive hook; which variable do I use in my bash script, or better yet, can you point me to a reference or example that can tell me what to use so I can parse it? – James Nine Feb 02 '11 at 01:56
  • 2
    For your convenience, I'll post the text from the link Pablo sent you here: "After the entire commit process is completed, the post-commit hook runs. It doesn’t take any parameters, but you can easily get the last commit by running git log -1 HEAD. Generally, this script is used for notification or something similar." – Dustin Feb 02 '11 at 02:51
  • For the answer to be actually useful, it should contain at least enough of the above comment to reasonably stand on its own. – tripleee Jan 10 '17 at 12:03