Git提交后钩子 - 在提交的文件上运行脚本

6

我能否看到一个示例后置钩子来在每个提交的文件上运行脚本?

例如:

git add file1
git add file2

git commit -am "my commit"

当钩子被触发时,它将执行:

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

最好的方法是添加一个参数来控制是否运行此钩子,例如:git commit -X… 执行此后提交钩子。最终可以使用别名 git-commitx
同样的版本也可以作为文件索引中的预提交钩子吗?如果在其中一个文件上执行脚本失败,我能否中止提交?

编辑:

这是我现在拥有的:
#!/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个回答

7

假设您在每个文件上执行的脚本不能立即在一个参数失败时设置为失败,则无法使用该xargs设置。您可以尝试像这样做:

#!/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

也许phpmd已经为您完成了这个任务?从您的问题中无法完全理解,但如果是这样的话,您只需要确保它是挂钩中的最后一个命令。管道的退出状态是其中最后一个命令(phpmd)的退出状态,而shell脚本的退出状态是它运行的最后一个命令的退出状态 - 因此,如果phpmd以错误状态退出,则挂钩脚本也将退出,如果它是预提交挂钩,则会导致git中止提交。

至于控制调用此挂钩的git-commit选项,除非您认为--no-verify(禁止所有提交挂钩)足够好,否则您可能有点运气不好。一个别名...最干净的方法可能是在别名中设置环境变量:

# 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...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接