最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 手写 git hooks 脚本(pre-commit、commit-msg)

    正文概述 掘金(谭光志)   2021-07-19   489

    简介

    Git 能在特定的重要动作发生时触发自定义脚本,其中比较常用的有:pre-commitcommit-msgpre-push 等钩子(hooks)。我们可以在 pre-commit 触发时进行代码格式验证,在 commit-msg 触发时对 commit 消息和提交用户进行验证,在 pre-push 触发时进行单元测试、e2e 测试等操作。

    Git 在执行 git init 进行初始化时,会在 .git/hooks 目录生成一系列的 hooks 脚本:

    手写 git hooks 脚本(pre-commit、commit-msg)

    从上图可以看到每个脚本的后缀都是以 .sample 结尾的,在这个时候,脚本是不会自动执行的。我们需要把后缀去掉之后才会生效,即将 pre-commit.sample 变成 pre-commit 才会起作用。

    本文主要是想介绍一下如何编写 git hooks 脚本,并且会编写两个 pre-commitcommit-msg 脚本作为示例,帮助大家更好的理解 git hooks 脚本。当然,在工作中还是建议使用现成的、开源的解决方案 husky。

    正文

    用于编写 git hooks 的脚本语言是没有限制的,你可以用 nodejsshellpythonruby等脚本语言,非常的灵活方便。

    下面我将用 shell 语言来演示一下如何编写 pre-commitcommit-msg 脚本。另外要注意的是,在执行这些脚本时,如果以非零的值退出程序,将会中断 git 的提交/推送流程。所以在 hooks 脚本中验证消息/代码不通过时,就可以用非零值进行退出,中断 git 流程。

    exit 1
    

    pre-commit

    pre-commit 钩子中要做的事情特别简单,只对要提交的代码格式进行检查,因此脚本代码比较少:

    #!/bin/sh
    npm run lint
    
    # 获取上面脚本的退出码
    exitCode="$?"
    exit $exitCode
    

    由于我在项目中已经配置好了相关的 eslint 配置以及 npm 脚本,因此在 pre-commit 中执行相关的 lint 命令就可以了,并且判断一下是否正常退出。

    // 在 package.json 文件中已配置好 lint 命令
    "scripts": {
        "lint": "eslint --ext .js src/"
     },
    

    下面看一个动图,当代码格式不正确的时候,进行 commit 就报错了:

    手写 git hooks 脚本(pre-commit、commit-msg)

    在修改代码格式后再进行提交,这时就不报错了:

    手写 git hooks 脚本(pre-commit、commit-msg)

    从动图中可以看出,这次 commit 已正常提交了。

    commit-msg

    commit-msg hooks 中,我们需要对 commit 消息和用户进行校验。

    #!/bin/sh
    
    # 用 `` 可以将命令的输出结果赋值给变量
    # 获取当前提交的 commit msg
    commit_msg=`cat $1`
    
    # 获取用户 email
    email=`git config user.email`
    msg_re="^(feat|fix|docs|style|refactor|perf|test|workflow|build|ci|chore|release|workflow)(\(.+\))?: .{1,100}"
    
    if [[ ! $commit_msg =~ $msg_re ]]
    then
    	echo "\n不合法的 commit 消息提交格式,请使用正确的格式:\
    	\nfeat: add comments\
    	\nfix: handle events on blur (close #28)\
    	\n详情请查看 git commit 提交规范:https://github.com/woai3c/Front-end-articles/blob/master/git%20commit%20style.md"
    
    	# 异常退出
    	exit 1
    fi
    

    commit-msg 钩子触发时,对应的脚本会接收到一个参数,这个参数就是 commit 消息,通过 cat $1 获取,并赋值给 commit_msg 变量。

    验证 commit 消息的正则比较简单,看代码即可。如果对 commit 提交规范有兴趣,可以看看我另一篇文章。

    对用户权限做判断则比较简单,只需要检查用户的邮箱或用户名就可以了(假设现在只有 abc 公司的员工才有权限提交代码)。

    email_re="@abc\.com"
    if [[ ! $email =~ $email_re ]]
    then
    	echo "此用户没有权限,具有权限的用户为: xxx@abc.com"
    
    	# 异常退出
    	exit 1
    fi
    

    下面用两个动图来分别演示一下校验 commit 消息和判断用户权限的过程:

    手写 git hooks 脚本(pre-commit、commit-msg)

    手写 git hooks 脚本(pre-commit、commit-msg)

    设置 git hooks 默认位置

    脚本可以正常执行只是第一步,还有一个问题是必须要解决的,那就是如何和同一项目的其他开发人员共享 git hooks 配置。因为 .git/hooks 目录不会随着提交一起推送到远程仓库。对于这个问题有两种解决方案:第一种是模仿 husky 做一个 npm 插件,在安装的时候自动在 .git/hooks 目录添加 hooks 脚本;第二种是将 hooks 脚本单独写在项目中的某个目录,然后在该项目安装依赖时,自动将该目录设置为 git 的 hooks 目录。

    接下来详细说说第二种方法的实现过程:

    1. npm install 执行完成后,自动执行 git config core.hooksPath hooks 命令。
    2. git config core.hooksPath hooks 命令将 git hooks 目录设置为项目根目录下的 hooks 目录。
    "scripts": {
        "lint": "eslint --ext .js src/",
        "postinstall": "git config core.hooksPath hooks"
    },
    

    总结

    其实本文适用的范围不仅仅局限于前端,而是适用所有使用了 git 作为版本控制的项目。例如安卓、ios、Java 等等。只是本文选择了前端项目作为示例。

    最近附上项目源码:github.com/woai3c/git-…

    参考资料

    • 自定义 Git - 使用强制策略的一个例子
    • Shell 教程

    起源地下载网 » 手写 git hooks 脚本(pre-commit、commit-msg)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元