git hook

hook

hook 翻译为钩子,简单说就是监听某个事件(操作),然后触发自定义逻辑
在 git 中可以监听 commit,push 等操作,在操作之前或之后触发对应的 hook,在 hook 中写自定义的逻辑,比如在提交之前做一些检查,检查未通过不允许提交

下面这些是 git hook 触发的时机

在这里插入图片描述
其中蓝色方块是某些操作之后触发,它不会阻塞操作,就是执行一些额外的操作
黄色和红色方块是某些操作之前触发,可以做一些检查,不满足条件会阻塞操作,区别在于黄色方块的操作可以跳过

克隆一个仓库并显示隐藏的文件,可以看到仓库根目录下的 .git 文件夹中有提供了一些 hook 例子,这些 hook 默认不生效,去掉 .sample 后缀才会生效
在这里插入图片描述
这些 hook 都是用 shell 命令编写的,查看 pre-commit

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	against=$(git hash-object -t tree /dev/null)
fi

allownonascii=$(git config --type=bool hooks.allownonascii)

exec 1>&2

if [ "$allownonascii" != "true" ] &&
	test $(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	cat <<\EOF
Error: Attempt to add a non-ASCII file name.
This can cause problems if you want to work with people on other platforms.
To be portable it is advisable to rename the file.
If you know what you are doing you can disable this check using:
  git config hooks.allownonascii true
EOF
	exit 1
fi

exec git diff-index --check --cached $against --

它会检查提交的文件名里是否有非 ASCII 码,exit 1 表示检查没有通过,exit 0 表示检查通过
这些 hook 我们可以修改逻辑,但是它只会在本地生效,因为 .git 文件夹里的修改不会上传到仓库,为了参与项目的人都能使用 hook,需要借助第三方工具来实现

commitlint + husky

首选需要安装 node.js,官网下载安装即可
在项目根目录安装

npm install --save-dev @commitlint/cli @commitlint/config-conventional

安装 commitlint/cli 和 commitlint/config-conventional 这两个包,并将其添加到 devDependencies(开发阶段的依赖,就是我们在开发过程中需要用的依赖,只在开发阶段起作用的),并将该信息保存到 package.json中

commitlint/cli 是一个命令行工具,用于校验 Git 提交信息的格式是否符合规范。
commitlint/config-conventional 是一个常用的配置文件,它定义了一些常见的 Git 提交信息规范,例如 Angular 的规范。它包含了一些预定义的规则,可以直接使用,也支持自定义规则

新建 commitlint.config.js 文件,增加配置项

module.exports = {
  // 继承的规则
  extends: ['@commitlint/config-conventional'],
  // 定义规则类型
  rules: {
    // type 类型定义,表示 git 提交的 type 必须在以下类型范围内
    'type-enum': [
      2,
      'always',
      [
        'feat', // 新功能 feature
        'fix', // 修复 bug
        'docs', // 文档注释
        'style', // 代码格式(不影响代码运行的变动)
        'refactor', // 重构(既不增加新功能,也不是修复bug)
        'perf', // 性能优化
        'test', // 增加测试
        'chore', // 构建过程或辅助工具的变动
        'revert', // 回退
        'build' // 打包
      ]
    ],
    // subject 大小写不做校验
    'subject-case': [0]
  }
}

rule由name和配置数组组成,如上面的:‘type-enum:[2, ‘always’, […]]’,数组中第一位为level,可选0,1,2,0为disable,1为warning,2为error,这里的 2 表示错误级别,表示如果提交消息不符合规则,将会以错误级别报错,第二位为应用与否,可选 always|never,always 表示规则必须被应用到每一个提交消息中,第三位该rule的值,这里定义了 git 提交的类型,提交信息的开头必须是上面定义的类型,如

fix: 修复了某个bug

安装 husky

npm install husky --save-dev

在 package.json 中添加 prepare 脚本并运行,创建 .husky 文件夹

npm pkg set scripts.prepare="husky install"
npm run prepare

将一个名为 pre-commit 的 git hook 添加到 .husky 目录中

npx husky add .husky/pre-commit "npm test"

这里的 “npm test” 是 hook 中的指令,生成后可以随意修改,比如检查文件的名称,路径是否合法

添加一个 commit-msg 钩子,它会在每次提交代码时运行 commitlint,以确保提交的消息符合规范

npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

修改文件做测试
在这里插入图片描述
提交信息的开头包含必须是配置中定义的类型(feat,fix等)才能提交

在这里插入图片描述
最后把生成的这些文件提交到仓库,参与项目的人提交时都会受到在 hook 中做检查

使用 hook 实现主仓库和子模块的联动操作

子模块

子模块相当于子仓库,就是把一个 git 仓库作为另一个 git 仓库的子仓库

git submodule add https://gitee.com/xxx/sub1.git

在仓库下执行 git submodule add url(仓库地址),就会添加一个子模块,这时会生成 .gitmodules 和 一个子模块的文件夹,.gitmodules 中记录子模块的路径和仓库地址

[submodule "sub1"]
	path = sub1
	url = https://gitee.com/xxx/sub1.git

初始化所有的子仓库并更新

git submodule update --init --recursive

修改提交后,在主仓库可以看到子模块后面有个commit hash 值,这对应子模块的某一个版本
在这里插入图片描述
当我们克隆一个包含子模块的仓库时,它默认是不生成子模块的内容,需要递归的方式克隆整个项目才行

git clone url --recursive

或者克隆的时候勾选 Recursive

在这里插入图片描述

联动

为了让主仓库更新时,子模块也更新,在 .husky 文件夹下添加一个新的 post-merge 这个 hook,使用 git pull 更新后会触发 post-merge,因为 git pull 就是 git fetch 和 git merge 的简写,在 post-merge 里更新子模块

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# git pull 触发 merge 操作,更新所有子仓库
git submodule foreach 'git pull'

exit 0

如果子模块有更新,主仓库没有更新,此时执行 git pull 不会触发 post-merge,因为没有发生 merge 操作

如果需要主仓库切分支时,子模块也切分支,需要添加 post-checkout 这个 hook。
在执行 git clone 和 git checkout 后会触发 post-checkout,在克隆仓库或切分支后,会检查是否有子模块,有就初始化子模块,主仓库切分支后,如果这个分支名称是dev开头,子模块也会切过去

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

## $1是HEAD的前一个SHA值,$2是HEAD的当前SHA值。如果$1和$2相同,表示没有切换分支
if [ "$1" = "$2" ]; then
  exit 0
fi

# git clone 也会触发 post-checkout
# 存在子模块且未初始化,则初始化并更新
if [ -f .gitmodules ]; then
  if git submodule status | grep -q '^[-]'; then
    git submodule update --init --recursive --remote --merge
  fi
else
  exit 0
fi

branch=$(git branch --show-current)
#echo "branch-name: $branch"
# branch为空跳过
if [ -z "$branch" ]; then
  exit 0
fi

#如果分支名以dev开头,子模块也切过去,没有对应分支则创建分支并切过去
if [[ $branch == dev* ]]; then
  git submodule foreach "git checkout -b $branch || git checkout $branch"
fi

exit 0

参考

git hook

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/27617.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java Web开发实战经典学习过程笔记

Java Web开发实战经典学习简单笔记 第一章 Java Web 开发简介 1.胖客户端程序指的是&#xff0c;当一个程序运行时需要一个单独的客户端程序支持(如&#xff1a;QQ)。瘦客户端程序在操作时不需要任何其他程序的安装(如&#xff1a;登录网上论坛&#xff0c;只需浏览器即可)。 2…

算法刷题-链表-反转链表

反转链表 206.反转链表思路C代码双指针法递归法其他语言版本使用虚拟头结点解决链表翻转使用栈解决反转链表的问题 反转链表的写法很简单&#xff0c;一些同学甚至可以背下来但过一阵就忘了该咋写&#xff0c;主要是因为没有理解真正的反转过程。 206.反转链表 力扣题目链接 …

4.使用Express跨域资源共享(继上一章)

4.5、CORS跨域资源共享 1.接口的跨域问题 刚才编写的GET和POST接口&#xff0c;存在一个很严重的问题&#xff1a;不支持跨域请求。 解决接口跨域问题的方案主要有两种&#xff1a; ①CORS&#xff08;主流的解决方案&#xff0c;推荐使用&#xff09; ②JSONP&#xff08…

6.11下周黄金行情分析及开盘多空交易策略

近期有哪些消息面影响黄金走势&#xff1f;下周黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;金价周五(6月8日)收低&#xff0c;但在美元整体走软的支撑下&#xff0c;本周录得连续第二周上升。美市尾盘&#xff0c;现货黄金收报1960.83美元/盎司&#xff0c;…

Seata介绍、原理、配置

目录 介绍&#xff1a; 核心组件&#xff1a; 原理&#xff1a; Seata 会有 4 种分布式事务解决方案&#xff0c;分别是 AT 模式、TCC 模式、Saga 模式和 XA 模式 AT模式原理&#xff1a; 一阶段&#xff1a; 二阶段提交&#xff1a; 二阶段回滚&#xff1a; Seata配置…

华为OD机试真题 JavaScript 实现【数字涂色】【2022Q4 100分】,附详细解题思路

一、题目描述 疫情过后&#xff0c;希望小学终于又重新开学了&#xff0c;三年二班开学第一天的任务是将后面的黑板报重新制作。 黑板上已经写上了N个正整数&#xff0c;同学们需要给这每个数分别上一种颜色。 为了让黑板报既美观又有学习意义&#xff0c;老师要求同种颜色的…

每个程序员都必须知道的8种通用数据结构

8种常用数据结构 数据结构是一种特殊的组织和存储数据的方式&#xff0c;可以使我们可以更高效地对存储的数据执行操作。数据结构在计算机科学和软件工程领域具有广泛而多样的用途。 几乎所有已开发的程序或软件系统都使用数据结构。此外&#xff0c;数据结构属于计算机科学和…

微服务eureka和nacos

服务远程调用 /*** 创建RestTemplate并注入Spring容器* return*/Beanpublic RestTemplate restTemplate(){return new RestTemplate();} Autowiredprivate RestTemplate restTemplate;public Order queryOrderById(Long orderId) {// 1.查询订单Order order orderMapper.fin…

JMeter 测试 ActiveMq

JMeter 测试 ActiveMq 的资料非常少&#xff0c; 我花了大量的时间才研究出来 关于ActiveMq 的文章请参考我另外的文章。 版本号: ActiveMq 版本号: 5.91 Jmeter 版本号: 1.13 添加ActiveMq 的jar包 将 ActiveMq 下的 "activemq-all-5.9.1.jar" 复制…

【2023】Redis cluster集群模式搭建

目录 1.cluster集群介绍2.搭建cluster集群2.1.架构图2.2.搭建集群2.2.1.创建所需配置文件2.2.2.创建集群所需容器2.2.3.创建集群&#xff1a;master1节点连接其他节点2.2.4.配置从节点&#xff0c;完成三主三从 3.在cluster集群内读写数据 1.cluster集群介绍 Redis Cluster是R…

[C++]异常笔记

我不怕练过一万种腿法的对手,就怕将一种腿法 练一万次的对手。 什么是C的异常 在C中&#xff0c;异常处理通常使用try-catch块来实现。try块用于包含可能会抛出异常的代码&#xff0c;而catch块用于捕获并处理异常。当异常被抛出时&#xff0c;程序会跳过try块中未执行…

【ABAP】数据类型(二)「预定义数据类型」

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后端的开发语言A…

一文读懂 Mysql MVCC

&#x1f495;&#x1f495; 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; 文章目录 1、什么是 MVCC2、什么是当前读、快照读3、MVCC 具体解决什么问题4、MVCC 的实现原理4.1、4个隐式字段4.2、undo 日志4.3、Read View 5、使用 MVCC 时&#xff0c;需…

【分布式系统与一致性协议】

分布式系统与一致性协议 CAP原理APCPCA总结BASE理论 一致性拜占庭将军问题 分布式系统是一个硬件或软件组件分布在不同的网络计算机上&#xff0c;彼此之间仅仅通过消息传递进行通信和协调的系统。 分布式系统的设计目标一般包含如下&#xff1a; 可用性&#xff1a;可用性是分…

JavaSE-04【方法】

文章目录 JavaSE-04【方法】第一章 方法1.1 方法定义的格式详解1.2 方法定义的三要素1.3 方法调用的流程图解1.4 方法定义的有无参数1.5 方法定义的有无返回值 第二章 方法调用方式以及注意事项2.1 方法调用的注意事项2.2 调用方法的三种形式 JavaSE-04【方法】 第一章 方法 …

【华为OD机试真题2023B卷 JAVAJS】评论转换输出

华为OD2023(B卷)机试题库全覆盖,刷题指南点这里 评论转换输出 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 在一个博客网站上,每篇博客都有评论。每一条评论都是一个非空英文字母字符串。 评论具有树状结构,除了根评论外,每个评论都有一个父评论。 当评论保…

再看const成员函数

文章目录 再看函数重载const成员函数保安&#xff08;const&#xff09;能保护所有人&#xff08;类成员&#xff09;吗&#xff1f;mutable修饰类成员 const/非const成员函数的复用 关于函数重载实际上我理解不是很深入&#xff0c;直接导致const成员函数这块出大问题&#xf…

chatgpt赋能python:Python如何升序输出?从入门到实践!

Python如何升序输出&#xff1f;从入门到实践&#xff01; 作为一门高级编程语言&#xff0c;Python是目前应用广泛且最为流行的一门语言之一。它逐渐成为开发者的首选语言&#xff0c;因为它易学易用&#xff0c;可读性强&#xff0c;支持多种编程范式&#xff0c;提供了强大…

【MySQL 数据库】9、存储过程

目录 一、存储过程是什么二、存储过程的基本语法三、MySQL 中的变量(1) 系统变量(2) 用户自定义变量(3) 局部变量 四、if 判断五、参数传递和返回值六、case 语句七、while 循环八、repeat 循环九、loop 循环十、游标十一、条件处理程序 一、存储过程是什么 &#x1f331; 存储…

Java反射与注解

文章目录 一、 注解1.简介2. 元注解3. 自定义注解 二、 反射1. 简介2. 理解Class类并获取Class实例3. 类的加载与初始化4. 类加载器ClassLoader5. 获取运行时类的完整结构6. 动态创建对象执行方法7. 反射操作泛型8. 反射操作注解 一、 注解 1.简介 Annotation是JDK5.0开始引入…