从 Git Hooks 说开去

最近我在一个咨询项目上,为了帮助客户规范代码提交信息,我们决定建议客户使用 git hooks来实现。

为此,我们大概了解了一下 Git Hooks的相关知识。

一、初识 Git Hooks

Git Hooks 是什么?

Git Hooks 是一系列脚本, Git 允许 Git 仓库在触发某些事件时,去执行这些脚本。 我们可以通过 Git Hooks 在开发生命周期的关键节点,触发自定义的操作。

这里的脚本可以是任何正确命名的可执行脚本。由此可见,Git Hooks 的灵活性还是很强的。

在一个 Git 仓库中,我们可以在.git/hooks中发现一系列的文件:

applypatch-msg.sample     pre-push.sample
commit-msg.sample         pre-rebase.sample
fsmonitor-watchman.sample pre-receive.sample
post-update.sample        prepare-commit-msg.sample
pre-applypatch.sample     update.sample
pre-commit.sample

这些文件都是不同的 Git Hooks 脚本, 当然,他们现在并不会执行。

Git 能识别的文件名是不带sample的,所以当我们把上述文件的sample后缀去掉时,这些脚本才是有效的。

另外,因为上述文件都是可执行的脚本,所以在执行时,要注意给与其相应的权限。

二、Git Hooks的版本化

我们在上面看到 Git Hooks 的相关脚本存放在 .git/hooks 目录下。但该目录并不被版本化,提交到远端。

但是对于团队来说,保证其可版本化是非常重要的功能,否则配置新脚本,或者对已有的脚本进行变化,都是一项浩大的工程。

经过简单的调研发现,无论是Java相关的技术栈,还是JS相关的技术栈,都有比较成熟的方案。

Java 相关的技术栈,比如 Spring 项目,Android项目等,可以使用Gradle的相关配置功能,将配置脚本纳入版本管理中,在gradle build时,再拷贝到 .git\hooks 目录中。 具体实现步骤,大家可以参见腾云的这个项目

Js 相关的技术栈,可以直接在Npm中使用使用 husky 来完成对应的配置。他依赖Npm的安装和配置,具体的使用方式可以参见他的项目主页

以上两种方式,都需要依靠特定的依赖管理工具才能完成。那依赖管理工具不支持,或者没有依赖管理工具,还想完成版本化管理 Git hooks, 怎么办呢?

Git hooks 的脚本文件都存放在.git\hooks目录下,但是该目录并不能被纳入版本管理中。经过查阅 git 的文档可知, 在17年 Git 提供了一项配置: core.hooksPath,通过它,可以将指定某个目录存放 git hook 的相关脚本。同时,该目录也可以纳入版本管理。

执行命令如下:

git config --add core.hookspath .mygithooks

执行该命令后,在提交时,会自动触发.mygithooks 目录下的脚本。

三、Git Hooks 的分类

Git Hooks 分两种,客户端钩子 、服务端钩子。 客户端钩子会被 commit,merge,rebase 等操作触发,而服务端会被push等操作触发。

1. 客户端钩子

客户端钩子 分为三种,提交工作流,电子邮件流,和其他。我们这里只讨论提交工作流和其他部分。

在 Git Hooks 中,若脚本以 exit 0退出应用,则流程会继续进行。若脚本以非0值退出,则流程会中断不会继续进行。

下图是提交工作流钩子的生命周期:

09-20-0-0.png

pre commit 不带任何参数,可以通过git diff 的形式获取变更的代码。一般用来检查即将提交的代码是否有效,比如是否能通过编译,是否能通过测试等。

prepare commit msg 带三个参数, 当前提交信息的文件路径,当前的提交类型,以及提交的SHA-1校验。 一般用来做提交信息的格式化,合并,整理等。

commit msg 带一个参数,即当前提交信息的文件路径。 一般用来检查提交信息格式等。

post commit 不带任何参数。 一般用于提交后发送通知等。

其他工作流包括pre-rebase, post-rewrite, post-merge, pre-push 这些在我们日常开发过程中用的比较少, 这里就不做介绍了。

使用git commit --no-verify 可以越过和commit相关的钩子,直接提交。

2. 服务端钩子

服务端的钩子在持续集成中,应用是很广泛的。

pre-receive 会处理来自客户端的推送。 常见的就是提交后触发CI,由CI返回结果来判断能否合入。

update 也会处理来自客户端的推送,区别是可以按照分支进行处理。 如果客户端同时推送了多个分支,仅有失败的分支会被拒绝。成功的分支仍会被更新。update 带三个参数,分别是引用分支的名字,推送前的SHA-1值, 需要更新的SHA-1值。

post-receive 在整个过程完结以后运行。 大家最熟悉的就是提交后触发测试,打包,部署等流程。

四、 Git Hooks的使用场景

Git Hooks 的本质是触发器,可以在 Git 的生命周期的某些阶段触发开发人员预先编写好的脚本。 所以其使用场景并不受限。

下面仅介绍一些我们在开发过程中可能会用到的场景。

  1. 客户端钩子

    因为客户端钩子仅在本地起作用,想要做出强制性的约束,还是只能依赖服务端的流程。

    所以客户端的钩子一般多用来做提示性,或触发一些重复手动工作。

    所以我们可以在客户端钩子中检查:

    暂存区是否还有未提交的代码。

    检查或者直接格式化提交信息。

    代码是否能够编译,是否能通过lint,是否能通过单元测试,是否达到单元测试覆盖率等等指标。

    在Push 时自动升级版本。

    在将多个提交合并成一个提交时,按照格式整理提交信息等。

  2. 服务端钩子

    服务端的钩子主要的作用有两个:一个是决定是否接受当前推送(pre-receiveupdate ),另外一个是在接受推送后(post-receive ), 触发其他操作等。

    服务端的钩子的使用场景,大家就很熟悉了,通过各种自动化的方式来对代码质量进行审查,来决定代码是否能够合入云端。如果不能合入,给出相应的提示。以及合入后,触发各种各种自动化的流程进行CICD流程。

推荐阅读:

https://wilsonmar.github.io/git-hooks/

https://githooks.com/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 名称 githooks-Git使用的挂钩。(githook在官网的介绍) 描述 如同其他许多的版本控制系统一样,G...
    BenjaminY阅读 4,084评论 1 3
  • 1.什么是 Git Hooks 如同其他许多的版本控制系统一样,Git 也具有在特定事件发生之前或之后执行特定脚本...
    就叫yang阅读 3,249评论 3 11
  • 1 简介 git hooks,即git 钩子,定义为能在特定的重要动作发生时触发自定义脚本。git 的hook分为...
    Separes阅读 9,704评论 0 3
  • 欢迎到个人博客阅读 前言 公司这边其实已经使用sonar对代码进行了统计,但需求想要更加明确的统计每个user单独...
    才兄说阅读 3,364评论 0 3
  • git hooks 使用 配置管理示意图 git hooks 使用说明 客户端 hookspre-commit 钩...
    天空中的海豚阅读 1,155评论 0 0