git-hook简介与使用

hook

hook,钩子:即某个时期或事件之前、之后执行和一些操作或脚本。与我们常说的中间件很相似。

git-hooks

git有很多hook,每当我们git init初始化一个git仓库时,都会创建一个.git的隐藏文件夹,git的hook就放在.git/hooks下。hooks以.sample为后缀的是示例文件。git-hooks有客户端hooks和服务端的hooks。

这里介绍客户端会用到的hooks

  • pre-commit: 钩子在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。
  • commit-msg: 钩子在启动提交信息编辑器之前,默认信息被创建之后运行。 它允许你编辑提交者所看到的默认信息。

git仓库根目录的隐藏文件夹.git里的git-hooks是不被git管理的,只存在于本地。所以无法让仓库中所有成员使用同样的hooks。这时候就需要通过工具库来使用git-hooks,就是husky。

husky

  • 安装 husky
shell 复制代码
pnpm install husky --save-dev
  • husky 初始化
shell 复制代码
npx husky install
  • 设置 package.json 的 prepare。来保证 husky 可以正常运行
shell 复制代码
npm set-script prepare "husky install"
  • 添加 git hooks
shell 复制代码
npx husky add .husky/${hook_name} ${command}

如此一来,我们进行git操作时,触发hook_name钩子从而运行command(命令)。

接下来我们就可以借助commitlint校验commit信息。借助lint-staged来实现对暂存区的代码进行风格校验和格式化。

commitlint

commitlint是对commit信息校验的一款npm包。

  • 安装
shell 复制代码
npm i @commitlint/cli @commitlint/config-conventional -D
  • 添加git-hook
shell 复制代码
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

现在我们只是增加了对commit message的校验,但是在使用 Git 过程中,填写 commit message其实是比较麻烦的。如果没有良好的 commit message 规范,commit历史就会很乱。这时就需要 commitizen 来协助开发者填写 commit 信息。

commitizen

commitizen是基于 Node.js 开发的 git commit 命令行工具,用来生成标准化的commit-message。commitizen 本身只提供命令行交互框架以及一些 git 命令的执行,实际的规则则需要通过适配器来定义,commitizen 留有对应的适配器接口。市面上有很多适配器,比如: cz-conventional-changelogcz-git。常见适配器生产commit-message模板

text 复制代码
<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>
  • 安装 commitizen
shell 复制代码
pnpm install commitizen -D
  • 初始化,参数含义:使用cz-git适配器初始化commitizen,并用pnpm安装依赖。
shell 复制代码
npx commitizen init cz-git --save-dev --save-exact --pnpm
go 复制代码
commitizen init 做了什么
1.  安装 `cz-git` 适配器 npm 模块
2.  将其保存到 package.json 的 devDependencies 中
3.   添加配置到 package.json 中 如下:
    "config": {  
        "commitizen": {  
            "path": "./node_modules/cz-git"  
            }  
        }
  • 新建 commitlint.config.js 文件:(对提交信息做格式检验的
js 复制代码
module.exports = {
ignores: [commit => commit === "init"],
extends: ["@commitlint/config-conventional"], 
rules: {
// @see: https://commitlint.js.org/#/reference-rules
"body-leading-blank": [2, "always"],
"footer-leading-blank": [1, "always"], 
"header-max-length": [2, "always", 108], 
"subject-empty": [2, "never"],
"type-empty": [2, "never"], 
"subject-case": [0], 
"type-enum": [ 2, "always", [ "feat", "fix", "docs", "style", "refactor", "perf", "test", "build", "ci", "chore", "revert", "wip", "workflow", "types", "release" ] ]
},
prompt: {
messages: {
type: "选择你要提交的类型 :", 
scope: "选择一个提交范围(可选):",
customScope: "请输入自定义的提交范围 :",
subject: "填写简短精炼的变更描述 :\n", 
body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n', 
footerPrefixsSelect: "选择关联issue前缀(可选):",
customFooterPrefixs: "输入自定义issue前缀 :",
footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",
confirmCommit: "是否提交或修改commit ?" }, 
types: [ 
{ value: "feat: 特性", name: "特性: 🚀 新增功能", emoji: "🚀" }, 
{ value: "fix: 修复", name: "修复: 🧩 修复缺陷", emoji: "🧩" }, 
{ value: "docs: 文档", name: "文档: 📚 文档变更", emoji: "📚" },
{ value: "style: 格式", name: "格式: 🎨 代码格式(不影响功能,例如空格、分号等格式修正)", emoji: "🎨" },
{ value: "refactor: 重构", name: "重构: ♻️ 代码重构(不包括 bug 修复、功能新增)", emoji: "♻️" }, { value: "perf: 性能", name: "性能: ⚡️ 性能优化", emoji: "⚡️" }, { value: "test: 测试", name: "测试: ✅ 添加疏漏测试或已有测试改动", emoji: "✅" }, { value: "chore: 构建", name: "构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)", emoji: "📦️" }, 
{ value: "ci: 集成", name: "集成: 🎡 修改 CI 配置、脚本", emoji: "🎡" },
{ value: "revert: 回退", name: "回退: ⏪️ 回滚 commit", emoji: "⏪️" },
{ value: "build: 打包", name: "打包: 🔨 项目打包发布", emoji: "🔨" }
], 
useEmoji: true,
themeColorCode: "", 
scopes: [], 
allowCustomScopes: true,
allowEmptyScopes: true,
customScopesAlign: "bottom",
customScopesAlias: "custom",
emptyScopesAlias: "empty", 
upperCaseSubject: false, 
allowBreakingChanges: ["feat", "fix"],
breaklineNumber: 100, breaklineChar: "|",
skipQuestions: [],
issuePrefixs: [{ value: "closed", name: "closed: ISSUES has been processed" }], 
customIssuePrefixsAlign: "top", 
emptyIssuePrefixsAlias: "skip",
customIssuePrefixsAlias: "custom",
allowCustomIssuePrefixs: true, 
allowEmptyIssuePrefixs: true,
confirmColorize: true, 
maxHeaderLength: Infinity,
maxSubjectLength: Infinity,
minSubjectLength: 0, 
scopeOverrides: undefined,
defaultBody: "", 
defaultIssues: "", 
defaultScope: "", 
defaultSubject: "" }
};
  • 配置 package.json 命令
json 复制代码
"scripts": {
    "commit": "git status && git add -A && git-cz" 
}

运行pnpm run commit以触发git-hook规范commit message

lint-staged

一般情况下 lint-staged 搭配着 Husky 一起使用。需要保证lint-staged 会在 pre-commit hook 中被运行。在使用lint-staged校验代码和代码风格时这里使用的是prettiereslint

  • 安装
shell 复制代码
pnpm install lint-staged --save-dev
  • 添加 git hooks
shell 复制代码
npx husky add .husky/pre-commit "npx lint-staged"
  • 配置

形式一:package.json 中添加一个 lint-staged 项。

json 复制代码
"lint-staged": {
   "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.json": ["prettier --write"],
    "*.vue": ["eslint --fix', 'prettier --write', 'stylelint --fix"],
    "*.{scss,css,sass,less,html}": ["stylelint --fix ", "prettier --write"],
    "*.md": ["prettier --write"]
  }

形式二:根目录添加一个 .lintstagedrc.json 文件。

json 复制代码
//.lintstagedrc.json
{
    "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.json": ["prettier --write"],
    "*.vue": ["eslint --fix', 'prettier --write', 'stylelint --fix"],
    "*.{scss,css,sass,less,html}": ["stylelint --fix ", "prettier --write"],
    "*.md": ["prettier --write"]
}

之后每次的pre-commit钩子触发都会执行代码校验和代码格式化。

相关推荐
遇到困难睡大觉哈哈2 分钟前
CSS中的Element语法
前端·css
Real_man8 分钟前
新物种与新法则:AI重塑开发与产品未来
前端·后端·面试
小彭努力中8 分钟前
147.在 Vue3 中使用 OpenLayers 地图上 ECharts 模拟飞机循环飞行
前端·javascript·vue.js·ecmascript·echarts
老马聊技术11 分钟前
日历插件-FullCalendar的详细使用
前端·javascript
咔咔一顿操作13 分钟前
Cesium实战:交互式多边形绘制与编辑功能完全指南(最终修复版)
前端·javascript·3d·vue
LuckyLay1 小时前
使用 Docker 搭建 Rust Web 应用开发环境——AI教你学Docker
前端·docker·rust
pobu1682 小时前
aksk前端签名实现
java·前端·javascript
烛阴2 小时前
带参数的Python装饰器原来这么简单,5分钟彻底掌握!
前端·python
0wioiw02 小时前
Flutter基础(前端教程⑤-组件重叠)
开发语言·前端·javascript
冰天糖葫芦2 小时前
VUE实现数字翻牌效果
前端·javascript·vue.js