• git hook相关内容


    一、Git钩子

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

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

    每一个使用了 git 的工程下面都有一个隐藏的 .git 文件夹。

    挂钩都被存储在 .git 目录下的 hooks 子目录中,即大部分项目中的 .git/hooks。 如下图:

    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 init 或git clone时,模板目录文件夹下的所有文件和目录都会被复制到.git文件夹。

    二、node项目下的git hook

    husky 是一个 Git Hook 工具。husky 其实就是一个为 git 客户端增加 hook 的工具。将其安装到所在仓库的过程中它会自动在.git/目录下增加相应的钩子实现在pre-commit阶段就执行一系列流程保证每一个commit 的正确性。部分 cd在 commit 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做代码检查

  • 相关阅读:
    五月杂题选做
    BJOI 2021 游记&题解
    U149858
    CF1037简要题解
    CF Round706简要题解
    联合省选 2020
    九省联考 2018 IIIDX
    九省联考 2018 秘密袭击
    AGC006F Balckout
    概率生成函数学习笔记
  • 原文地址:https://www.cnblogs.com/94pm/p/13860799.html
Copyright © 2020-2023  润新知