gitLab hooks简介和简单使用

Git Hooks 就是在Git执行特定事件(如commit、push、receive等)后触发运行的脚本

Git Hooks 能做什么

Git Hooks是定制化的脚本程序,所以它实现的功能与相应的git动作相关,如下几个简单例子:
1.多人开发代码语法、规范强制统一
2.commit message 格式化、是否符合某种规范
3.如果有需要,测试用例的检测
4.服务器代码有新的更新的时候通知所有开发成员
5.代码提交后的项目自动打包(git receive之后) 等等

简介

Git hooks大体上分为两类:客户端钩子和服务器端钩子,如下 先从一张图了解一下Hooks的阶段:

在这里插入图片描述

1、 客户端钩子

项目的hooks如下,地址为当前项目的.git/hooks目录下,打开后可以看到如下文件,里面有示例shell脚本,默认是不启用的,只有去掉.sample后缀才能生效,里面的脚本代码可以根据实际情况编写。

pre-commit

        钩子在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用 git commit --no-verify 来绕过这个环节。 你可以利用该钩子,来检查代码风格是否一致(运行类似 lint 的程序)、尾随空白字符是否存在(自带的钩子就是这么做的),或新方法的文档是否适当。

prepare-commit-msg

        钩子在启动提交信息编辑器之前,默认信息被创建之后运行。 它允许你编辑提交者所看到的默认信息。 该钩子接收一些选项:存有当前提交信息的文件的路径、提交类型和修补提交的提交的 SHA-1 校验。 它对一般的提交来说并没有什么用;然而对那些会自动产生默认信息的提交,如提交信息模板、合并提交、压缩提交和修订提交等非常实用。 你可以结合提交模板来使用它,动态地插入信息。

commit-msg

        钩子接收一个参数,此参数即上文提到的,存有当前提交信息的临时文件的路径。 如果该钩子脚本以非零值退出,Git 将放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息。 在本章的最后一节,我们将展示如何使用该钩子来核对提交信息是否遵循指定的模板。

post-commit

        钩子在整个提交过程完成后运行。 它不接收任何参数,但你可以很容易地通过运行 git log -1 HEAD 来获得最后一次的提交信息。 该钩子一般用于通知之类的事情。

post-applypatch

        运行于提交产生之后,是在 git am 运行期间最后被调用的钩子。 你可以用它把结果通知给一个小组或所拉取的补丁的作者。 但你没办法用它停止打补丁的过程。

pre-rebase

        钩子运行于变基之前,以非零值退出可以中止变基的过程。 你可以使用这个钩子来禁止对已经推送的提交变基。 Git 自带的 pre-rebase 钩子示例就是这么做的,不过它所做的一些假设可能与你的工作流程不匹配。

post-rewrite

        钩子被那些会替换提交记录的命令调用,比如 git commit --amend 和 git rebase(不过不包括 git filter-branch)。 它唯一的参数是触发重写的命令名,同时从标准输入中接受一系列重写的提交记录。 这个钩子的用途很大程度上跟 post-checkout 和 post-merge 差不多。

在 git checkout 成功运行后,post-checkout 钩子会被调用。你可以根据你的项目环境用它调整你的工作目录。 其中包括放入大的二进制文件、自动生成文档或进行其他类似这样的操作。

在 git merge 成功运行后,post-merge 钩子会被调用。 你可以用它恢复 Git 无法跟踪的工作区数据,比如权限数据。 这个钩子也可以用来验证某些在 Git 控制之外的文件是否存在,这样你就能在工作区改变时,把这些文件复制进来。

pre-push

        钩子会在 git push 运行期间, 更新了远程引用但尚未传送对象时被调用。 它接受远程分支的名字和位置作为参数,同时从标准输入中读取一系列待更新的引用。 你可以在推送开始之前,用它验证对引用的更新操作(一个非零的退出码将终止推送过程)。

Git 的一些日常操作在运行时,偶尔会调用 git gc --auto 进行垃圾回收。 pre-auto-gc 钩子会在垃圾回收开始之前被调用,可以用它来提醒你现在要回收垃圾了,或者依情形判断是否要中断回收。

1.1、 客户端hooks钩子的使用

示例:写一个脚本,检查commit信息的长度不能小于10,否则不能提交

在.git/hooks目录下找到commit-msg.sample,重命名为commit-msg,脚本如下:

#!/bin/sh

#拿到提交的commit备注信息
MSG=`awk '{printf("%s",$0)}' $1`

#判断
if [ ${#MSG} -lt 10 ]
then
echo "-------------"
echo "commit message 只有${#MSG}字符"
echo "message的长度不能小于10, 本次提交失败,请完善commit message,再提交"
echo "-------------"
exit 1; #非0退出表示校验不通过,git将拒绝提交
fi

保存后自动生效。

1.2、 自定义客户端hooks目录

默认客户端hook是在项目的.git/hooks/ 目录下,默认是独立项目之外,不受版本控制的,如果要修改脚本,需要每个开发都复制一份或者都自己修改,比较麻烦。因此可以通过修改客户端配置来实现hooks受git版本控制。

如果需要使其随项目受控制,需要自定义一个目录存放hook脚本,例如:在项目.git目录同级目录下新建.githooks目录:

然后执行命令把默认目录改为我们的自定义目录,在.githooks同级目录下执行git命令:

 git config core.hooksPath .githooks

此时就可以把 .githooks包含到项目里跟随项目了

2、 服务端钩子

pre-receive

        处理来自客户端的推送操作时,最先被调用的脚本是 pre-receive。 它从标准输入获取一系列被推送的引用。如果它以非零值退出,所有的推送内容都不会被接受。 你可以用这个钩子阻止对引用进行非快进(non-fast-forward)的更新,或者对该推送所修改的所有引用和文件进行访问控制。

update

        update 脚本和 pre-receive 脚本十分类似,不同之处在于它会为每一个准备更新的分支各运行一次。 假如推送者同时向多个分支推送内容,pre-receive 只运行一次,相比之下 update 则会为每一个被推送的分支各运行一次。 它不会从标准输入读取内容,而是接受三个参数:引用的名字(分支),推送前的引用指向的内容的 SHA-1 值,以及用户准备推送的内容的 SHA-1 值。 如果 update 脚本以非零值退出,只有相应的那一个引用会被拒绝;其余的依然会被更新。

post-receive

        post-receive 挂钩在整个过程完结以后运行,可以用来更新其他系统服务或者通知用户。 它接受与 pre-receive 相同的标准输入数据。 它的用途包括给某个邮件列表发信,通知持续集成(continous integration)的服务器, 或者更新问题追踪系统(ticket-tracking system) —— 甚至可以通过分析提交信息来决定某个问题(ticket)是否应该被开启,修改或者关闭。 该脚本无法终止推送进程,不过客户端在它结束运行之前将保持连接状态, 所以如果你想做其他操作需谨慎使用它,因为它将耗费你很长的一段时间。

2.1、 服务端hooks钩子的使用

在服务端代码仓库的项目下找到.git目录,新建目录custom_hooks,把脚本 pre_receive 放入其中,可执行权限设置为777。

查找服务端项目的xxx.git目录:

可以通过gitLab的配置文件查询到存储目录,如果gitLab存储是用的hash散列存储的方式,如下:

这种存储方式就不能直观的在仓库里面找到对应的项目,在shell中执行命令(echo -n 项目id | sha256sum)生成一个hash值,按这个值去找这个git库的代码位置:

 hash值的开头几个数字正好是对应的目录

编写好的脚本存放位置:

示例:写一个脚本,检查commit信息的长度不能小于5,否则不能push成功

脚本内容:

#!/bin/bash
#pre-receive script
# push代码后会执行该脚本,校验不通过就拒绝push
# 注:一次push可能包含好多次commit,所以拿到的是list,需要遍历校验

# 校验的方法
validate_ref()
{
# --- Arguments
oldrev=$(git rev-parse $1)
newrev=$(git rev-parse $2)
refname="$3"

#拿到每次commit的id
commitList=`git rev-list $oldrev..$newrev`
# 输出
echo $commitList

split=($commitList)
for s in ${split[@]}
do
echo "============"
echo "$s"
# 根据commit id获取提交是的备注信息
msg=`git cat-file commit $s | sed '1,/^$/d'`
echo $msg
if [ ${#msg} -lt 5 ];
then
echo "Commit message length less than 5";
exit 1; #非0退出表示校验不通过,git将拒绝push;
else
echo "success";
fi
done

}


# 调用校验的方法
fail=""

# Allow dual mode: run from the command line just like the update hook, or
# if no arguments are given then run as a hook script
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
PAGER= validate_ref $2 $3 $1
else
while read oldrev newrev refname
do
validate_ref $oldrev $newrev $refname
done
fi

if [ -n "$fail" ]; then
exit $fail
fi

使用服务端代码校验commit备注是不合适的:因为一次push可能包含了多次commit,如果某一次commit不通过,需要在客户端重新找到那一次的commit修改备注后再提交。

3、 gitLab webHooks

Gitlab中的一个功能, 当项目进行了某项操作后(如push代码),代码托管平台就会调用给定的URL,发送一条POST请求。至于URL那边的服务器,接收到请求之后就可以进行某些操作,例如:自动进行测试、构建、部署等等;目前用得最多的就是:push代码成功后,调用Jenkins进行自动打包部署服务。

webHooks调用接口时会自动发送项目相关的参数,接口端JsonObject接收即可

3.1 gitLab webHooks使用

示例:push代码成功后调用我们服务的一个接口,接口拿到项目相关的信息

 登录gitlab,找到webhook配置项

 在接口填写处填入接口地址,例如:http://127.0.0.1:8080/demo/webHookTest01

对应的服务端接口代码:


@PostMapping("/webHookTest01")
 public void webHookTest01(@RequestBody JSONObject jsonObject) {
 // 可接收到gitLab push代码的相关信息
 log.info("hookRequest:{}", JSON.toJSONString(jsonObject));
 }

push代码成功后,会自动调用接口,并且接口会接收到相关项目参数信息。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GitLab 的 Server Hooks 可以让你在 GitLab 服务器上的 Git 仓库中的特定事件触发时运行脚本。你可以使用这些 Server Hooks 来校验提交的用户名和邮箱。具体的文档如下: 1. 打开 GitLab 服务器上的 Git 仓库,并转到仓库设置页面。 2. 在设置页面中,选择“Integrations”选项卡,并找到“Server Hooks”部分。 3. 在“Server Hooks”部分中,找到“Custom HTTP POST”选项,并单击“Add webhook”按钮。 4. 在“Add webhook”窗口中,输入一个名称和 URL。 URL 应该指向包含你的脚本的服务器端点。 5. 在“Trigger”下拉菜单中,选择“Push events”。 6. 在“Secret Token”字段中,添加一个令牌以确保只有知道该令牌的人才能访问你的服务器端点。 7. 点击“Add webhook”按钮。 8. 创建一个脚本,校验提交的用户名和邮箱。你可以使用类似以下的 Python 脚本: ```python #!/usr/bin/env python import sys def validate(commit_author_name, commit_author_email): if 'example.com' in commit_author_email: print('Commit rejected: invalid email') return False elif 'John' not in commit_author_name: print('Commit rejected: invalid username') return False else: return True if __name__ == '__main__': commit_author_name = sys.argv[1] commit_author_email = sys.argv[2] if not validate(commit_author_name, commit_author_email): sys.exit(1) ``` 9. 将脚本上传到你的服务器,并确保 GitLab 服务器上的 Git 仓库可以访问该脚本。 10. 确保脚本有执行权限。 11. 提交一个带有无效用户名或邮箱的 commit,以测试你的脚本是否生效。 这样,你就可以使用 Server Hooks 校验提交的用户名和邮箱了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值