从commit校验失效问题探究husky原理
一、背景
之前创建的项目,发现代码 commit 提交的时候没有了任何校验,具体表现:
- 一是 feat fix 等主题格式校验没有了
- 二是代码 lint 不通过也能提交
尝试解决这个问题,并深入了解husky的实现原理,将相关的一些知识点分享下。
二、lint配套工具
完整的一套代码规范工具,可能包含:husky + lint-staged + eslint + stylelint + prettier 等
1. git 钩子:
git 本身提供多个生命周期钩子,常见的例如 pre-commit、commit-msg、pre-push 等。
pre-commit 钩子:
在 git commit 命令执行之前触发,配合指定的脚本命令可用来执行代码 lint 校验、代码格式化、跑测试用例等任务,以确保在提交代码之前达到一定的质量标准。
commit-msg 钩子:
是在 git 编辑提交信息之后、提交之前触发,可用于 commit 信息的格式校验。
2. husky:
husky 是一个用来简化 Git 钩子管理的工具。它可以帮助你在 Git 的生命周期事件(如 pre-commit、pre-push 等)中轻松地添加脚本,并且与常用的 js 工具和任务管理器(npm、yarn)集成良好。
3. lint-staged:
lint-staged 用于结合 husky 和 pre-commit,能做到只对 Git 暂存区(git add . 之后)的文件 运行校验任务,从而实现只处理改动的文件,提升commit效率,在大型项目上效果更加明显。
4. eslint:
eslint 是用于对 js 和 jsx 做代码校验的工具,通过静态分析代码来快速地发现和修复一些代码语法问题,帮助前端开发规范代码、提高效率。
5. stylelint:
stylelint 是用于对 css 样式 做代码校验的工具,同上述 eslint 类似,帮助前端开发在编写 css 及 less等预处理器代码时避免犯错,提升开发效率。
6. prettier:
prettier 是目前最常用的前端代码格式化工具,支持多项规则配置,帮助统一代码风格。适当的配置后可以与上述 eslint 和 stylelint 兼容。
三、husky原理
疑问:
- git 是全局命令,而 husky 只是项目里引入的一个插件,它是怎么和全局的 git 命令产生联系的?
- 我们通过 git commit -m “xxx” 提交代码时,husky 做了什么?
(以下以 mac os 下 husky v9 版本示例)
1. husky初始化:
1)配置方式:
- 一般会在项目 package.json 的 scripts 里配置下 prepare 命令(“prepare”: “husky”),用于执行 husky 的初始化。prepare 是 npm 的钩子,在项目 npm i 时会自动执行 npm run prepare。
2)解析husky命令:
- 执行 husky 命令 实际就是执行 node_modules/.bin/husky 文件,里面没啥东西,主要是三块,自动修改 husky init 命令、错误命令输出处理、执行 index.mjs,显然核心代码在 index.mjs 里。
- 找到 node_modules/husky/index.mjs 文件,解析下里面的核心代码动作:
- 执行命令 git config core.hooksPath .husky/_ ,创建目录 .husky/_
- .husky/_ 里写入 .gitignore 内容为 *
- 复制 node_modules/husky/husky 文件内容到 .husky/_ 的 h 文件
- 遍历 l 数组,即支持的所有 git 钩子,复制到 .husky/_ 下同名文件,内容统一为 . “${0%/*}/h”
- .husky/_ 里创建文件 husky.sh,内容为空。

3)解析说明:
-
一般来说项目都是用 git 来作为代码版本控制工具,每个项目在 git init 初始化后,根目录都会生成一个 .git 隐藏文件夹,里面是 git 的配置文件 及 代码记录信息。
-
husky 在执行初始化命令后,会自动修改 git 的 hooks 目录,具体表现为在项目 .git 文件夹下的 config 文件里新增了 core.hooksPath 配置,指向项目的 .husky/_ 目录,这样执行 git commit 命令时就会自动寻找项目 .husky/_ 下的钩子文件。
- 未指定时,默认的 hooks 目录是 .git/hooks

-
然后在 .husky/_ 目录下自动生成 git 钩子文件 和 一些执行脚本。
*
2. husky执行流程:
(以项目 pre-commit 钩子为例)
1)开始运行 commit
- 修改项目文件,运行 git add .
- 运行 git commit -m “xxx”,开始流程。
2)读取 hooks 目录配置
- git工具会去项目的 .git 目录 config 文件里读取 core.hooksPath 目录配置,指向了.husky/_ 目录
3)寻找 pre-commit 业务脚本
- 首先在 .husky/_ 目录下找到 pre-commit 钩子文件,即 .husky//pre-commit,并执行,实际执行是指向了同目录下的 h 文件,即 .husky//h

- ${0%/*}:0表示当前执行的脚本路径,%/* 表示从字符串末尾匹配 /*,保留前面部分
- 执行 h 文件,里面基本是统一读取 husky 配置 以及 做了错误校验,然后实际执行是指向了上一级目录下的同名文件,即 .husky/pre-commit,这个就是我们要寻找的业务侧钩子脚本。

- ${0##*/}:##/* 表示最大化匹配 */,保留后面部分
4)执行 pre-commit 脚本
- 执行 .husky/pre-commit 文件,这个就是真正的业务侧钩子脚本,里面内容是就是跑 lint-staged。
5)执行 lint-staged 脚本
- 运行 lint-staged 命令时,首先是要读取 lint-staged 配置,在 .lintstagedrc 文件里(部分项目可能在 package.json 里配置的),里面就是对不同类型的文件跑不同的命令
6)执行成功 or 失败
- 如果命令执行成功,pre-commit 钩子就顺利执行完成了,接着会往下走流程,走 commit-msg 钩子,做 提交信息的格式校验,大致流程类似。
- 如果执行异常,钩子会中断,不会往下走,commit 失败。如异常命令有抛出信息会在命令行输出。
四、问题解决:
回到最初提到的 bigfish 项目 commit 失效问题。

1. 问题原因:
在代码提交时有warning提示,翻译下来就是 .husky 文件夹下的两个文件是不可执行的,
其实就是 .husky 里的这两个钩子文件没有被赋予可执行权限。
- 如果这俩文件是在Windows下创建后上传的,在mac下把项目拉下来后就不可执行了。
2. 解决方式:
方式一:
- 在项目根目录下运行命令,给钩子文件手动赋予可执行权限,
- chmod +x .husky/commit-msg .husky/pre-commit

方式二:(推荐)
- 升级 husky 版本到 v9,修改 package.json 里的 preare 命令为 “husky”,然后运行 npm run prepare
- husky v9 版本更新日志里有一项变更,通过自动设置正确的文件权限,解决了 husky v8 中的这个权限问题。
- husky v9 版本更新日志里有一项变更,通过自动设置正确的文件权限,解决了 husky v8 中的这个权限问题。
3. 全局format:
解决完后,建议执行一次 npm run format 命令,即 prettier,对全局做一次代码格式化。
因为每次 commit 校验的时候项目虽然会自动执行 format,但只对修改的文件执行,建议提前对项目所有文件 format 处理下。
五、IDE自带git工具问题:
可能有些人会遇到使用 vscode 或 在线编辑器 等IDE时,自带的 git 管理工具无法 commit,执行时会立即报错。
1. 问题原因:
可能你使用了 nvm 等 node 管理工具,使用 git 工具可能会无法 commit,原因是执行 husky 命令时识别不出 node 环境,详见链接,需要补充环境配置。
2. 解决方式:
在 .husky/pre-commit 和 .husky/commit-msg 文件内容里的 npx执行命令 之前,添加环境配置代码:
待添加的环境配置代码内容:
- 方式一:(个人搜寻并组合出来的)
if [ -s "$HOME/.nvm/nvm.sh" ]; then# First load nvm and provide access to the nvm command.export NVM_DIR="$HOME/.nvm/nvm.sh". "$(dirname $NVM_DIR)/nvm.sh"# Use the nvm ls command to detect the version being used.export NVM_DIR="$HOME/.nvm"a=$(nvm ls | grep 'node')b=${a#*(-> }v=${b%%[)| ]*}# Export the current version in your path for husky to find.export PATH="$NVM_DIR/versions/node/$v/bin:$PATH"
fi
- 方式二:(官方文档里的,待验证)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # 加载 nvm
相关文章:
从commit校验失效问题探究husky原理
一、背景 之前创建的项目,发现代码 commit 提交的时候没有了任何校验,具体表现: 一是 feat fix 等主题格式校验没有了二是代码 lint 不通过也能提交 尝试解决这个问题,并深入了解husky的实现原理,将相关的一些知识点…...
Azure OpenAI 服务上线具有音频和语音功能的 GPT-4o-Realtime-Preview,免费申请试用
微软宣布 GPT-4o-Realtime-Preview 音频和语音公开预览版的推出,这是对Microsoft Azure OpenAI 服务的重大增强,增加了高级语音功能并扩展了 GPT-4o 的多模式产品。 这一里程碑进一步巩固了 Azure 在人工智能领域的领导地位,尤其是在语音技术…...
基于IMX6UL的EPIT的定时器实验
定时器是最常用的外设,常常需要使用定时器来完成精准的定时功能,I.MX6U 提供了多 种硬件定时器,有些定时器功能非常强大。本章我们从最基本的 EPIT 定时器开始,学习如何配置EPIT 定时器,使其按照给定的时间,…...
FreeMarker模板引擎入门:从基础到实践的全面指南
前言 什么是FreeMarker FreeMarker是一个基于模板生成文本输出的通用工具,它使用纯Java编写,能够生成HTML、XML、JSON、RTF、Java源代码等多种格式的文本。FreeMarker模板引擎允许将数据模型与模板文件结合,生成动态的文本输出,广…...
YOLOv8模型改进 第十讲 添加全维度动态卷积(Omni-dimensional Dynamic Convolution,ODConv)
本篇文章将介绍一种全新的改进机制——全维度动态卷积ODConv,并展示其在YOLOv8中的实际应用。现全维动态卷积(Omni-dimensional Dynamic Convolution,ODConv)是一种先进的动态卷积设计,旨在通过引入多维注意力机制来提…...
【环境搭建】远程服务器搭建ElasticSearch
参考: 非常详细的阿里云服务器安装ElasticSearch过程..._阿里云服务器使用elasticsearch-CSDN博客 服务器平台:AutoDL 注意: 1、切换为非root用户,su 新用户名,否则ES无法启动 2、安装过程中没有出现设置账号密码…...
机器学习与神经网络:诺贝尔物理学奖的新篇章
机器学习与神经网络:诺贝尔物理学奖的新篇章 引言 近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上的首次。诺贝尔物理学奖通常授予在自然现象和物理物质研究方面做出重大贡献的科学家。然而,今年…...
倍福TwinCAT程序中遇到的bug
文章目录 问题描述:TwinCAT嵌入式控制器CX5140在上电启动后,X001网口接网线通讯灯不亮,软件扫描不到硬件网口 解决方法:硬件断电重启后,X001网口恢复正常 问题描述:TwinCAT软件点击激活配置后,…...
R语言实现logistic回归曲线绘制
方式一:编制函数 x<-rnorm(10000)#设置随机种子 #编写绘图函数代码快 f <- function(x){y 1/(1 exp(-x))plot(x,y)}#sigmoid函数 f(x) 方式二:Sigmoid函数代码 x<-rnorm(10000)#设置随机种子 #编写绘图函数代码块 #y<-1/(1exp(-x)) y&…...
零宽字符(ZWSP)
前言 一个“所见非所得”的问题,示例如下: 查看原始DOM发现存在特殊字符: zero-width-space(ZWSP) 零宽空格是一种不可打印的Unicode字符,用于可能需要换行处。 在HTML中,零宽空格可以替代标…...
作业 定时发送邮件
[rootlocalhost zyc]# date -s 12:28 2024年 10月 15日 星期二 12:28:00 CST [rootlocalhost zyc]# vim /etc/chrony.conf [rootlocalhost zyc]# systemctl restart chronyd [rootlocalhost zyc]# date 2024年 10月 15日 星期二 12:36:00 CST [rootlocalhost zyc]# chronyc s…...
【排序】——2.快速排序法(含优化)
快速排序法 递归法 霍尔版本(左右指针法) 1.思路 1、选出一个key,一般是最左边或是最右边的。 2、定义一个begin和一个end,begin从左向右走,end从右向左走。(需要注意的是:若选择最左边的数据作为key,则…...
AnaTraf | 网络分析系统:高效IT运维工具
目录 什么是网络分析系统? 网络分析系统的核心功能 二、网络分析系统在IT运维中的重要性 案例分析:如何快速应对网络拥塞 技巧分享:如何使用网络分析系统优化带宽 网络分析系统的部署与最佳实践 确定监控范围与关键设备 分析结果的可…...
踩坑日记:线上接口超时问题排查
1.背景: 上线后,功能测试. 进入小程序页面发现很慢,耗时超过5秒,打开skywalking发现大量接口耗时都很高. 2.top命令 服务器top命令查看cpu资源发现占用并不高 3.mysql查看sql运行情况 # 当前运行的所有事务 select * from information_schema.innodb_trx; 1 | …...
C语言中的段错误(Segmentation Fault):底层原理及解决方法
引言 在C语言编程中,“段错误”(通常由操作系统信号 SIGSEGV 触发)是一种常见的异常情况,它表明程序试图访问不受保护的内存区域。本文将深入探讨段错误的原因、底层原理、常见情况以及如何调试和解决这类错误。 段错误的定义 …...
1.两数之和 暴力枚举和暴力搜索法
1. 两数之和 已解答 简单 相关标签 相关企业 提示 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相…...
你的收入达到了缴纳个人所得税的标准了吗?
在现代社会,个人所得税作为一种重要的税收形式,已经渗透到了我们每个人的日常生活中。它不仅关乎国家的财政收入,更与每个纳税人的切身利益息息相关。那么,你是否真正了解个人所得税的缴纳标准、计算方法以及相关的税收优惠政策呢…...
【C++贪心】2086. 喂食仓鼠的最小食物桶数|1622
本文涉及知识点 C贪心 LeetCode2086. 喂食仓鼠的最小食物桶数 给你一个下标从 0 开始的字符串 hamsters ,其中 hamsters[i] 要么是: ‘H’ 表示有一个仓鼠在下标 i ,或者’.’ 表示下标 i 是空的。 你将要在空的位置上添加一定数量的食物桶…...
notepad++中实现代码整体缩进和退格
我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 🎓擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号:乡下小哥编程。回复 Java全套视频教程 或 前端全套视频教…...
如何调整配置请款单上的立账条件
顾问配置的立账条件取的是供应商档案里面的参数。与实际需求是不相匹配的。采购员商谈的立账条件经常是变化的。 措施:修改模板中立几账条件的OQL语句。 如下: select UFIDA::U9::AP::APBill::APBillHead.APBillLines.AccrueTerm.Name as 立账条件_名…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...






