git代码提交 设置日志模板 对用户提交日志注释进行校验

背景:

由于公司项目管理需要,对开发人员的提交日志进行规范性约束。作为兼职的devops工程师,责无旁贷的去吭哧吭哧的研究了。公司主要使用git管理代码,gogs托管。作为领导眼中分分钟解决的问题,在真实上手研究还是需要一些时间成本的(鄙人主职还是研发)。

思路:

1、利用度娘和biying搜索了大量解决方案,发现都是指向git hook这个钩子来实现具体的业务场景。

比如 [1] 通过修改客户端的prepare-commit-msg.sample和commit-msg.sample,实现客户端的commit校验,但必须开发人员自己在库中的git/hook目录下修改相应文件,很难控制约束不太自觉的人员;又如 [2] 以Android项目为例子,使用Gradle脚本,当用户执行构建操作的时候,我们执行配置提交模板的脚本,通过脚本将配置的模板拷贝到用户的".git/hooks"目录下。再如 [3] 提出了一种解决.git文件夹不会被git跟踪,所以.git/hooks目录下的hooks钩子无法提交,就不能和他人共享钩子脚本。通过第三方的插件如:husky和yorkie解决上述问题。但上述三种方案都是在客户端侧对git提交的注释进行约束,不太能满足我们的诉求。

2、[3] 和 [4] 中还描述了hook是分客户端hook和服务器hook的,pre-receive、update和post-receive是服务器hook,只需要修改对应代码库的服务器hook文件,就可以对所有开发人员的push 提交注释进行校验。于是思考服务器hook也许可以解决我们的问题。

3、思考如何在执行pre-receive时获取注销,并对注释格式进行校验。[5] 和[6] 给了我启发。

解决方案

1、修改代码库中git/hook目录下的pre-receive

regex="^修改类型:(新功能|缺陷) TB编号\+主题:.{1,100} 是否自测:(是|否)"

## echo "regex: "$regex

## 定义注释出错提示信息
tips_msg="修改类型:新功能 TB编号+主题:××× 内容 是否自测:是"

validate_commit_message() {
oldrev=$(git rev-parse $1)
newrev=$(git rev-parse $2)
refname="$3"
#echo 'Old version: '$oldrev
#echo 'New version: '$newrev
#echo 'Branch: '$refname

## git 命令
#GITCMD="git"
## 按时间倒序列出 commit 找出两个版本之间差异的版本号集合 oldrev~newrev
commitList=$(git rev-list $oldrev..$newrev)
#echo 'commitList: '$commitList

split=($commitList)
#echo 'split: '$split

# 遍历数组
for s in ${split[@]}; do
#echo “$s”
#通过版本号获取仓库中对象实体的类型、大小和内容的信息
#比如提交人、作者、邮件、提交时间、提交内容等
currentContent=$(git cat-file commit $s)
#echo 'Commit obj: '$currentContent
#获取提交内容
msg=$(git cat-file commit $s | sed '1,/^$/d')
#echo 'msg: '$msg

## merge合并分之直接放行
if [[ $msg == *"Merge branch"* ]]; then
echo "Merge branch...skip the checking"
else
## 做内容校验
match=$(echo $msg | grep -nE "(${regex})")
echo 'Match result: '$match

## 找到匹配说明是符合规范的
if [ "${match}" != "" ]; then
## 校验注释长度
msg_length=${#msg}
#echo "Msg length: ${msg_length}"
if [[ ${msg_length} -lt ${COMMIT_MESSAGE_MIN_LENGTH} ]]; then
echo -e "Error: Commit message should be bigger than ${COMMIT_MESSAGE_MIN_LENGTH} and current commit message length: ${msg_length}"
exit 1
fi

### 找到匹配内容做相应处理,如fix ,校验pom文件等
#if [[ "${match}" =~ "fix:" ]]; then
## 如果是修补bug,规范有点获取到fix中的ID,然后调用禅道对外的API关闭,其他场景类似
#fi

# 是否开启校验和master分支
isMaster=$(echo $refname | grep "master$")
if [ -n "$isMaster" ]; then
# 如果是master分支,并且pom文件发生了变更,判断pom文件是否含有sonapshot的引用
pomfile=$(git diff --name-only ${oldrev} ${newrev} | grep -e "pom\.xml")
if [[ "${pomfile}" != "" ]]; then
#echo $pomfile
## 获取pom文件更新的内容
pomcontent=$(git show $newrev:$pomfile)
#echo $pomcontent
## 校验pom文件是否包含snapshot版本
if [[ $pomcontent =~ 'SNAPSHOT' ]]; then
echo -e "Error: Snapshot version cannot exist in master branch!"
exit 1
fi
fi
fi

## 其他操作
echo "Commit Success!"
else
echo -e "Error: 提交的注释必须采用如下模板 [修改类型:(新功能|缺陷) TB编号+主题:(DMP-××× 主题内容) 是否自测:(是|否)] 注释示例:${tips_msg}"
exit 1
fi
fi
done
}

####### 执行入口###########
pre_receive() {
validate_commit_message $1 $2 $3
}

if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
# Output to the terminal in command line mode - if someone wanted to
# resend an email; they could redirect the output to sendmail
# themselves
#pre_receive $2 $3 $1
echo $1'+'$2'+'$3
else
while read oldrev newrev refname; do
#pre_receive $oldrev $newrev $refname
pre_receive $oldrev $newrev $refname
done
fi

"/home/git/gogs/gogs" hook --config='/home/git/gogs/custom/conf/app.ini' pre-receive

2、commit后 push到远端服务器 若注释不符合规范

 3、git commit --amend 修改注释 [7]

 4、修改注释成满足要求格式后push成功

 

 同样可以在gogs管理侧更新web hook

 

 

#!/bin/sh
#
# An example hook script to make use of push options.
# The example simply echoes all push options that start with 'echoback='
# and rejects all pushes when the "reject" push option is used.
#
# To enable this hook, rename this file to "pre-receive".

if test -n "$GIT_PUSH_OPTION_COUNT"
then
i=0
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
do
eval "value=\$GIT_PUSH_OPTION_$i"
case "$value" in
echoback=*)
echo "echo from the pre-receive-hook: ${value#*=}" >&2
;;
reject)
exit 1
esac
i=$((i + 1))
done
fi

 

 

 

 

 

参考:

[1] https://zhuanlan.zhihu.com/p/456519458

[2] https://juejin.cn/post/7208111879151009848

[3] https://juejin.cn/post/6974301879731748900

[4] https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

[5] https://blog.csdn.net/xiaoll880214/article/details/105916898

[6] https://www.zhihu.com/question/65604891

[7] https://blog.csdn.net/c46550/article/details/116574128

 

posted @ 2023-07-04 11:00  cosmocosmo  阅读(650)  评论(0编辑  收藏  举报