git hook相关内容

摘要:
将一个命名正确且可执行的文件放入Git目录下的hooks子目录中,以激活hook脚本,Git将一直调用该脚本。如果钩子以非零值退出,Git将放弃提交,但您可以使用gitcommit--no verify绕过此阶段。在开发团队中维护钩子更为复杂,因为git/hooks目录不会与项目一起复制,也不受版本控制的影响。Husky实际上是一个向git客户端添加钩子的工具。

一、Git钩子

Git 能在特定的重要动作发生时触发自定义脚本,它能完成下列一些很常用的场景:

1.多人开发代码语法、规范强制统一
2.commit message 格式化、是否符合某种规范
3.如果有需要,测试用例的检测
4.服务器代码有新的更新的时候通知所有开发成员
5.代码提交后的项目自动打包(git receive之后) 等等...

每一个使用了 git 的工程下面都有一个隐藏的 .git 文件夹。
git hook相关内容第1张

挂钩都被存储在 .git 目录下的 hooks 子目录中,即大部分项目中的 .git/hooks。 如下图:
git hook相关内容第2张

Git 默认会放置一些脚本样本在这个目录中,除了可以作为挂钩使用,这些样本本身是可以独立使用的。所有的样本都是shell脚本,其中一些还包含了Perl的脚本。不过,任何正确命名的可执行脚本都可以正常使用 ,也可以用Ruby或Python,或其他脚本语言。

上图是git 初始化的时候生成的默认钩子,已包含了大部分可以使用的钩子,但是 .sample 拓展名防止它们默认被执行。为了安装一个钩子,你只需要去掉 .sample 拓展名。或者你要写一个新的脚本,你只需添加一个文件名和上述匹配的新文件,去掉.sample拓展名。把一个正确命名且可执行的文件放入 Git 目录下的 hooks子目录中,可以激活该挂钩脚本,之后他一直会被 Git 调用。

钩子分为客户端和服务端的,客户端的常用的钩子如下:

  • pre-commit钩子在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用git commit --no-verify来绕过这个环节。 你可以利用该钩子,来检查代码风格是否一致(运行类似lint的程序)、尾随空白字符是否存在(自带的钩子就是这么做的),或新方法的文档是否适当。
  • prepare-commit-msg钩子在启动提交信息编辑器之前,默认信息被创建之后运行。 它允许你编辑提交者所看到的默认信息。 该钩子接收一些选项:存有当前提交信息的文件的路径、提交类型和修补提交的提交的 SHA-1 校验。
  • commit-msg钩子接收一个参数,此参数即上文提到的,存有当前提交信息的临时文件的路径。 如果该钩子脚本以非零值退出,Git 将放弃提交,因此,可以用来在提交通过前验证项目状态或提交信息。 在本章的最后一节,我们将展示如何使用该钩子来核对提交信息是否遵循指定的模板。
  • post-commit钩子在整个提交过程完成后运行。 它不接收任何参数 该钩子一般用于通知之类的事情。

对于任何Git仓库来说钩子都是本地的,而且它不会随着git clone一起复制到新的仓库。而且,因为钩子是本地的,任何能接触得到仓库的人都可以修改。在开发团队中维护钩子是比较复杂的,因为.git/hooks目录不随你的项目一起拷贝,也不受版本控制影响。一个简单的解决办法是把你的钩子存在项目的实际目录中(在.git外)。这样你就可以像其他文件一样进行版本控制。作为备选方案,Git同样提供了一个模板目录机制来更简单地自动安装钩子。每次你使用git initgit clone时,模板目录文件夹下的所有文件和目录都会被复制到.git文件夹。

二、node项目下的git hook

husky 是一个 Git Hook 工具。husky 其实就是一个为 git 客户端增加 hook 的工具。将其安装到所在仓库的过程中它会自动在.git/目录下增加相应的钩子实现在pre-commit阶段就执行一系列流程保证每一个commit的正确性。部分cdcommit stage执行的命令可以挪动到本地执行,比如 lint 检查、比如单元测试。当然,pre-commit阶段执行的命令当然要保证其速度不要太慢,每次commit都等很久也不是什么好的体验。

husky Github

下面使用husky来实现在提交前检查是否有测试快照,提交信息是否符合书写规范的例子

npm i husky happy-git-commit-message-checker -D

package.json中增加如下代码(husky版本大于0.14的写法):

"husky": {
    "hooks": {
        "pre-commit": "node ./scripts/pre-commit.js",
        "commit-msg": "node ./scripts/commit-msg.js",
    }
}

./scripts/pre-commit.js(检查是否有测试快照用的)

const childProcess = require('child_process');
const fs = require('fs');
const path = require('path');
const fileMaxSize = 6 * 1024 * 1024; //最大6MB
childProcess.exec('git status --short -u', (error, stdout) =>{
    console.log('检测.snap快照文件体积');
    if(error) {
        console.log(error);
        process.exitCode = 1; //禁止提交
    } else{
        const paths = stdout.split(/s/);
        for (let i = 0; i < paths.length; i++) {
            const pt =path.resolve(process.cwd(), paths[i]);
            if (/.snap$/.test(pt)) {
                //是快照文件
let stats;
                try{
                    stats =fs.statSync(pt);
                    if (stats.size >fileMaxSize) {
                        console.log(`x ${paths[i]} ${stats.size}Byte (单个快照文件体积最大6MB)`);
                        process.exitCode = 1; //禁止提交
                        return;
                    }
                    console.log(`√ ${paths[i]} ${stats.size}Byte`);
                } catch(e) {
                    //
}
            }
        }
    }
});
./scripts/commit-msg.js(提交信息规范检查)
我们要求的提交信息的规则如下:
  • 一律以【xx页】描述【xx模块】描述的形式书写代码注释

  • 优先使用【xx页】描述

  • 描述需尽可能详细

  • 涉及多个页面,每个页面一行,分开描述

const fs = require('fs');
const runner = require('happy-git-commit-message-checker').runner;

console.log('检测message书写规范');
try{
    let message = fs.readFileSync('./.git/COMMIT_EDITMSG', 'utf-8');
    const lines = message.split('
');
    if (!lines[lines.length - 1]) {
        lines.pop();
    }
    message = lines.join('
');
    runner(message, ['[bB]uild(.*?)']);
} catch(e) {
    console.log('检测程序运行出错...', e);
}

如何获取commit message?

需要调用者自己读取/.git/COMMIT_EDITMSG文件内容,在commit-msg钩子触发时,Git会自动将message写入COMMIT_EDITMSG文件,读取即可

配合lint-staged做代码检查

免责声明:文章转载自《git hook相关内容》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Gym 101147G 第二类斯特林数Java项目命名规范下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

两台电脑对码云上面的项目进行迭代

几个基本概念 本地仓库: 本机上某个存放代码的仓库。 远程仓库: 码云服务器上的代码仓库。 重要提醒: 当我们在本地操作(新增、删除、修改)文件、目录时,并将其提交(commit),就是提交到了本地仓库。注意:所有的改动只是放到了本地仓库,并没有上传到服务器的远程仓库。怎么将本地仓库与远程仓库关联起来呢? 需先将本地仓库与远程仓库关联起来,就可将本地仓库中...

centos 下用shell删除多个目录下删除指定目录下创建日期大于30天的.log .txt文件

#删除指定目录下创建日期大于30天的.log .txt文件(如果目录下文件总数少于10个,就不删除),删除的文件记录写入到日志 #!/bin/bash #待删除的文件路径数组,多个目录换行 locations=( /root/logs/web1/ /root/logs/web2/ /root/logs/web3/ ) #输出的文件...

Linux系统的相关知识、常用命令及拓展、centos 7网卡配置

(本文仅为平时学习记录,若有错误请大佬指出,如果本文能帮到你那我也是很开心啦)   一、Linux系统的相关知识 1.Linux中根目录下所有文件夹的含义和用途 目录 功能 /bin 存放可执行文件 /dev 存放设备文件 (如:网卡、CPU) /media 存放可移除设备文件 (如:U盘、CD/DVD、VMTools) /opt 存放...

at_today git--一文弄懂git的工作区、索引区、本地仓库、远程仓库以及add、commit、push三个操作

git中文件所在位置有四个,在工作区内、在索引区内、在本地仓库、在远程仓库。处于四个位置中文件的状态分别为untracked、unmodified、modified、staged。通过三个操作可以把文件进行状态转移:git add 把工作区文件添加到索引区;git commit 把索引区文件添加到本地仓库;git push 把本地仓库文件添加到远程仓库。...

.gitkeep

看一个开源项目中有个.gitkeep文件,不知道是干嘛用的查询知道git是不允许提交一个空的目录到版本库上的,可以在空的文件夹里面建立一个.gitkeep文件,然后提交去即可。其实在git中 .gitkeep 就是一个占位符。可以用其他 比如 .nofile等文件作为占位符。...

网站项目开发规范

网站项目开发规范   总 论   本规范既是一个开发规范,也是一个脚本语言参考,本规范并不是一个一成不变的必须严格遵守的条文,特殊情况下要灵活运用,做一定的变通。但是,请大家千万不要随意更改规范。如果有任何问题,请及时与我联系,我会及时更改本规范的相关代码样例和文档。    基 本 要 求   1. 在网站根目录中开设images common te...