一、场景说明
服务端要求,git进行提交的时候,检验提交的格式如下,需要添加钩子
@所有人所有人的遵循一下提交规范,不要再111222了
【D】XXX表示删除
【M】XXX表示修改
【A】XXX表示新增
【U】XXX表示优化
每次提交只写一行消息不要有特殊字符,内容写的至少自己明白,如果不规范提交,我会直接进行
【回退操作】白搞
Git钩子
整个核心流程是使用了Git钩子,钩子分成两种,一种是客户端的钩子,另外一种是服务端的。我们这里使用的是服务端的钩子,服务端钩子有三个:pre-receive、update和post-receive。
pre-receive
预提交钩子,它是服务端最先调用的钩子,我们可以使用此钩子来指定强制执行的开发策略,例如拒绝一些糟糕内容的提交。
update
update钩子在pre-receive之后被调用,它们工作原理类似,它会在真实提交之前执行,可以拒绝提交。与pre-receive不同的是,它会为每一个准备更新的分支各运行一次。也就是说我们同时向多个分支推送内容,pre-receive只运行一次,而update则会为每一个分支各运行一次。
post-receive
此钩子在成功推送之后调用,可以用来更新服务和通知等等。例如,后端提交了接口代码,可以利用此钩子更新接口代码。
了解了上面几个钩子,我们选择了使用post-receive钩子来更新同步代码。
本地钩子,请自行参考https://www.jianshu.com/p/68131fd0c503
服务端的钩子
hook 配置
找到要配置仓库在 gitlab 中存储的路径,但因 gitlab 的仓库自某个版本开始采用 hash 存储,我们想要知道仓库对应的物理路径,需要到 gitlab 的 postgresql 数据库中的表 project_repositories 中,根据 project_id 能拿到对应的物理路径;
数据库查找项目的物理路劲
方法1:先网页打开获取id
一般就是在项目名的下面,如图,如果没有,就找到设置里面找就找到了
如上,获取的ip是392,执行下面命令
## 如果不知道是那个用户,可以 grep psql | grep /etc/passwd
### 查询物理地址
sudo gitlab-psql -d gitlabhq_production -c "SELECT * FROM project_repositories WHERE project_id = 392;"
# disk_path
#--------------------------------------------------------------------------------
# @hashed/6e/a2/6ea2fdb3399f4d2e806beb01e9a3371bd622bed6a409acf3151818d738c370ec
#(1 row)
对应的路劲是,前面加上/var/opt/gitlab/git-data/repositories/+物理地址
gitlab# pwd
#/var/opt/gitlab/git-data/repositories/@hashed/6e/a2/6ea2fdb3399f4d2e806beb01e9a3371bd622bed6a409acf3151818d738c370ec.git
方法2:直接通过链接查
缺点:如果有项目名重名的话,无法确定,需要用方法1打开网页确认。建议用方法1
如知道链接
http://xxxx/root/gouzi
项目名,就是gouzi
gitlab# sudo gitlab-psql -d gitlabhq_production -c "SELECT pr.disk_path FROM projects p INNER JOIN project_repositories pr ON p.id = pr.project_id WHERE p.path = 'gouzi';"
# disk_path
#--------------------------------------------------------------------------------
# @hashed/6e/a2/6ea2fdb3399f4d2e806beb01e9a3371bd622bed6a409acf3151818d738c370ec
编写钩子脚本
一般hooks是系统自带的,如果没有,可以自己建,为了防止和系统的钩子冲突,可以使用custom_hooks(用户自定义钩子)
cd /var/opt/gitlab/git-data/repositories/@hashed/6e/a2/6ea2fdb3399f4d2e806beb01e9a3371bd622bed6a409acf3151818d738c370ec.git
mkdir custom_hooks
cat > custom_hooks/pre-receive << EOF
#!/bin/sh
# 读取所有提交信息
while read oldrev newrev refname; do
# 获取最近一次提交的commit ID
commit=\$(git rev-list -n 1 \${newrev})
# 读取提交信息
COMMIT_MSG=\$(git log --format=%B -n 1 \$commit)
# 提交信息规范正则表达式
echo ""
echo "================================格式检查============================================"
echo "Commit message: \$COMMIT_MSG" >&2
PATTERN='^【[DMAU]】.+$'
# 检查提交信息是否符合规范
if ! echo "\$COMMIT_MSG" | grep -Eq "\$PATTERN"; then
echo "提交信息不符合规范,请按照以下格式进行提交:"
echo "【D】XXX表示删除"
echo "【M】XXX表示修改"
echo "【A】XXX表示新增"
echo "【U】XXX表示优化"
echo "每次提交只写一行消息不要有特殊字符,内容写的至少自己明白"
echo "提交已退回,请重新执行commit改名 如 git commit --amend -m \"【A】tan\""
echo "================================驳回提交============================================"
echo ""
echo ""
exit 1
fi
echo "================================格式ok================================================"
done
EOF
## 改用户名,加执行权限
chown git:git custom_hooks -R
chmod +x custom_hooks/pre-receive
可以在服务端简单测试
#获取最新的提交哈希值:
gitlab# git log --oneline -n 2
#e419b7a (HEAD -> Develop) 【A】测试提交
#616b286 【A】测试提交
echo "616b286 e419b7a refname" | ./custom_hooks/pre-receive
#================================格式检查============================================
#Commit message: 【A】测试提交
#================================格式ok================================================
客户端测试
演示不符合规范提交
### 下载gouzi.git
git clone http://xxxx/root/gouzi.git
cd gouzi
echo 123 > testfile.txt
## 演示不符合规范提交
git add -A && git commit -m "[A] 测试提交" && git push origin Develop
#Writing objects: 100% (6/6), 517 bytes | 0 bytes/s, done.
#Total 6 (delta 2), reused 0 (delta 0)
#remote:
#remote: ================================格式检查============================================
#remote: Commit message: [A] 测试提交
#remote: 提交信息不符合规范,请按照以下格式进行提交:
#remote: 【D】XXX表示删除
#remote: 【M】XXX表示修改
#remote: 【A】XXX表示新增
#remote: 【U】XXX表示优化
#remote: 每次提交只写一行消息不要有特殊字符,内容写的至少自己明白
#remote: 提交已退回,请重新执行commit改名 如 git commit --amend -m "【A】tan"
#remote: ================================驳回提交============================================
#remote:
#remote:
#To http://git.yuetanggame.com/root/gouzi.git
# ! [remote rejected] Develop -> Develop (pre-receive hook declined)
#error: failed to push some refs to 'http://xxxx/root/gouzi.git'
错误后,修改名称提交
git commit --amend -m "【A】tan" && git push origin Develop
其他问题
已经push了2次以上,有本地记录,导致提交的时候,提交2份以上,不能通过,如下
remote:
remote: ================================格式检查============================================
remote: Commit message: 【A】tan
remote: ================================格式ok================================================
remote:
remote: ================================格式检查============================================
remote: Commit message: [A] 测试提交
remote: 提交信息不符合规范,请按照以下格式进行提交:
remote: 【D】XXX表示删除
remote: 【M】XXX表示修改
remote: 【A】XXX表示新增
remote: 【U】XXX表示优化
remote: 每次提交只写一行消息不要有特殊字符,内容写的至少自己明白
remote: 提交已退回,请重新执行commit改名 如 git commit --amend -m "【A】tan"
remote: ================================驳回提交============================================
remote:
remote:
To http://git.yuetanggame.com/root/gouzi.git
! [remote rejected] Develop -> Develop (pre-receive hook declined)
error: failed to push some refs to 'http://git.yuetanggame.com/root/gouzi.git'
上面的Commit message: [A] 测试提交 和 Commit message: 【A】tan
一个是最新的符合的,一个是旧的,提交的时候,有2份,导致检查不通过
解决办法
# 执行n次,有多少份,就执行多少次(重置到最新的提交---会删除最新的几份)
git reset --soft HEAD~2
git add -A && git commit -m "【A】测试提交" && git push origin Develop
### 如果提示还有,那就是提交了更多次,因为这个信息只显示最近的2次,你再次上面执行即可
Comments | NOTHING