views:

86

answers:

1

Hello,

Can I see somewhere an example post-commit hook to run a script on each commited file?

eg.

git add file1
git add file2

git commit -am "my commit"

and the hook executes:

myscript -myparams "file1"
myscript -myparams "file2"

The best would be to have parameter to commit command to run this hook or not, eg. git commit -X… executes this post commit hook. Eventually an alias like git-commitx.

How about the same version as a pre-commit hook on files in index? Can I abort a commit when execution of the scripts fails on one of the files?

Edit:

Here is what I have now:

#!/bin/sh                                     
#.git/hooks/post-commit
dir=`pwd`
echo ----------------------------------------------
echo PHP Mess Detector results for commited files:
echo ----------------------------------------------
git show --pretty="format:" --name-only  | grep '\.php$' | xargs -i phpmd $dir/'{}' text codesize,unused$
echo ----------------------------------------------
+1  A: 

Assuming the script you execute on each file can't be set up to fail immediately when it fails on one argument, you can't use that xargs setup. You'll could do something like this:

#!/bin/bash

# for a pre-commit hook, use --cached instead of HEAD^ HEAD
IFS=$'\n'
git diff --name-only HEAD^ HEAD | grep '\.php$' |
while read file; do
    # exit immediately if the script fails
    my_script "$file" || exit $?
done

But perhaps phpmd will do this for you already? Couldn't quite understand from your question, but if it does, all you have to do is make sure it's the last command in the hook. The exit status of a pipeline is the exit status of the last command in it (phpmd), and the exit status of a shell script is the exit status of the last command it ran - so if phpmd exits with error status, the hook script will, and if it's a pre-commit hook, this will cause git to abort the commit.

As for an option to git-commit to control invocation of this hook, you're kind of out of luck, unless you consider --no-verify (which suppresses all commit hooks) good enough. An alias... the cleanest way to do that would be to set an environment variable in the alias, probably:

# gitconfig
[alias]
    commitx = "!run_my_hook=1; git commit"

# your script
#!/bin/bash
# if the variable's empty, exit immediately
if [ -z "$run_my_hook" ]; then
    exit 0;
fi
# rest of script here...
Jefromi