客户端钩子 pre-commit
pre-commit
钩子属于客户端钩子,当用户在本地键入提交信息前运行(即:执行 git commit 的真正操作之前被触发),可用于检查即将提交的快照。如:检查代码格式、触发代码质量检测。如果 pre-commit
钩子以非 0 值退出,那么 Git 也将放弃本次的 Commit 操作。可以使用 git commit --no-verify
#!/bin/sh
# 定义受保护的分支的表达式
protected_branch='master|dev|feature-20[0-9]+$'
# 检查当前推送的远程环境是否为公司仓库项目地址
strict=$(git remote get-url --push `git remote` | grep -c qeeq.cn)
# 获取当前分支名
current_branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
# 严谨模式-禁止在保护分支直接 commit 信息
if [ $strict == 1 ] && [[ "$current_branch" =~ $protected_branch ]]; then
echo -e ".git/hooks: Do not commit to protected branch:$current_branch\n"
exit 1
fi
# 在 commit 操作前:使用 gofmt 进行格式化提交的 *.go 文件再添加到待 commit 文件中
# 检测是否安装 gofmt
command -v gofmt >/dev/null 2>&1 && {
# 获取暂存区中待 commit 的 *.go 文件
golang_files=$(git diff --cached --name-only --diff-filter=ACM -- '*.go')
for FILE in $files
do
gofmt -w $FILE
echo "格式化:"$FILE
git add $FILE
done
}
# 最后至关重要!!!
# 防止上述命令有非成功推出,shell脚本默认返回 $?
# return 只能用于 function 中
exit 0
客户端钩子 commit-msg
commit-msg
钩子会在用户输入完提交信息退出编辑时被自动触发,触发时会传入一个参数 .git/COMMIT_EDITMSG
。常用于校验用户的 commit message 是否符合规范
$GIT_DIR/COMMIT_EDITMSG
文件记录了用户git commit -m "message"
中的 Message 信息
#!/bin/sh
# 定义提交日志格式标准
format_commit_msg="Format of the commit message is as follows: \
\n\n<type>[(scope>)]: <summary> \
\n<BLANK LINE> \
\n[<body>] \
\n<BLANK LINE> \
\n[<footer>]"
# 触发时会传入一个参数 `.git/COMMIT_EDITMSG`
# 获取提交的 commit msg
commit_msg=$(cat $1)
# 定义提交规范正则匹配
reg='^(build|chore|ci|docs|style|feat|fix|perf|refactor|test|revert)(\(.+\))?: .{1,150}'
# 匹配是否符合规范
# gpre -E 按照正则表达式进行匹配
# -i 忽略大小写
# -q 静默方式执行,即:不产生输出.若 $? 为零值(成功)则走if条件,非零(异常)走else
if ! cat $1 | grep -Eiq "$reg"
then
echo -e $format_commit_msg
exit 1
fi
# 最后返回 0 值,异常值由各校验模块自行 exit
exit 0
阅读参考:
-
Git diff 参数
--diff-filter=[(A|C|D|M|R|T|U|X|B)… [*]]
Select only files that are
- Added (A)
- Copied (C)
- Deleted (D)
- Modified (M)
- Renamed (R)
- have their type (i.e. regular file, symlink, submodule, …) changed (T)
- have their are Unmerged (U)
- have their are Unknown (X)
- have had their pairing Broken (B)
Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected.