和其他 Version Control System 一样,git 也有方法来触发自定义脚本。
两类 hooks:
- client hooks
- server hooks
Installing a hook
hook 脚本在 hooks
子目录下,大部分是 .git/hooks
下。在使用 git init
之后就会初始化一些 sample 脚本,在 hooks 下都以 .sample
结尾,如果要使用则需要将 .sample
后缀去掉。
Client-side Hooks
pre-commit
pre-commit
hook 会在输入 commit message 之前被执行。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# save the file as <git_directory>/.git/hooks/pre-commit | |
echo "Running Maven clean test for errors" | |
# retrieving current working directory | |
CWD=`pwd` | |
MAIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | |
# go to main project dir | |
cd $MAIN_DIR/../../ | |
# running maven clean test | |
mvn clean test | |
if [ $? -ne 0 ]; then | |
"Error while testing the code" | |
# go back to current working dir | |
cd $CWD | |
exit 1 | |
fi | |
# go back to current working dir | |
cd $CWD |
通常可以在该 hook 中检查代码是否被提交,运行 test,代码格式检查,或者其他 lint 工具检查。如果脚本返回 non-zero 值会阻断 commit。
prepare-commit-msg
prepare-commit-msg
hook 会在 commit message 编辑器被调用前,在默认 message 被创建后被触发。这可以使得你可以自定义默认 message。这个 hook 接受一些参数:
- commit message 的文件路径
- commit 类型
- 如果是 amended 提交则包含 commit SHA-1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This way you can customize which branches should be skipped when | |
# prepending commit message. | |
if [ -z "$BRANCHES_TO_SKIP" ]; then | |
BRANCHES_TO_SKIP=(master develop test) | |
fi | |
BRANCH_NAME=$(git symbolic-ref --short HEAD) | |
BRANCH_NAME="${BRANCH_NAME##*/}" | |
BRANCH_EXCLUDED=$(printf "%s\n" "${BRANCHES_TO_SKIP[@]}" | grep -c "^$BRANCH_NAME$") | |
BRANCH_IN_COMMIT=$(grep -c "\[$BRANCH_NAME\]" $1) | |
if [ -n "$BRANCH_NAME" ] && ! [[ $BRANCH_EXCLUDED -eq 1 ]] && ! [[ $BRANCH_IN_COMMIT -ge 1 ]]; then | |
sed -i.bak -e "1s/^/[$BRANCH_NAME] /" $1 | |
fi |
commit-msg
commit-msg
hook 接受一个参数,可以在该 hook 中检查 commit message。
post-commit
在整个 commit 结束后, post-commit
hook 会执行。不接受任何参数。通常该 hook 用来发送一些通知。