Gitru:Rust打造的零依赖Git提交信息校验工具,如何实现疑问?
摘要:gitru 基于 Git 的 commit-msg Hook 实现,用于在提交阶段自动校验提交信息格式。 在团队协作开发中,规范的 Git 提交信息是代码追溯、版本管理、自动生成变更日志的基础。 但现实往往是: 人工约束容易遗漏 手动配置
gitru 基于 Git 的 commit-msg Hook 实现,用于在提交阶段自动校验提交信息格式。
在团队协作开发中,规范的 Git 提交信息是代码追溯、版本管理、自动生成变更日志的基础。
但现实往往是:
人工约束容易遗漏
手动配置 Hook 繁琐
提交信息格式随心所欲
生成 changelog 时异常痛苦
因此,必须由工具来保证提交信息的规范性。
市面上已有不少成熟工具,但大多基于 Node.js / Python / Shell 实现。问题是:
只是想校验一个字符串,却要先安装 Node 或 Python
版本不一致可能导致各种奇怪的问题
国内下载依赖速度慢甚至失败
安装一个工具可能要拉下一堆包
属于“操作一大堆,却还没开始进入正题”。
这些对普通开发者,尤其是新手,并不友好。
当然,这并不是否定这些工具。相反,它们非常优秀,本项目开发过程中也使用了著名的 pre-commit。与这些成熟工具相比,gitru 甚至连 hello-world 都算不上,只是一个更轻、更简单的选择。
基于以上考虑,再加上 Rust 非常适合编写 CLI 工具,于是就有了 gitru。
✨ 项目特点
🦀 Rust 编写,零依赖二进制分发
下载即可运行,无需 Node、Python 或虚拟环境。
(虽然我不想把“Rust 编写”当成卖点,免得被误会成 Rust 传教士,但和其他成熟工具相比,这确实是 gitru 少数能拿得出手的特点之一。)
⚙️ TOML 格式自定义规则
简单、清晰、易读、易维护。
⏭️ 支持通过关键字跳过校验
适用于自动化提交、紧急修复等场景。
🇨🇳 支持中文提交信息校验
不会误判中文标点,对中文开发者更友好。
🎨 错误信息带颜色输出
更直观、更易读。
🔍 支持 Footer 关键字拼写校验(Spell Check)
当提交信息疑似拼写错误时,gitru 会自动检测并给出友好提示,避免因拼写错误导致自动化流程失效。(当然,这部分依赖算法和用户配置,体验远不如当下的ai)
📘 Conventional Commits 简介
在介绍 gitru 的使用前,必须先了解业内广泛采用的提交规范 ——
Conventional Commits。
它定义了提交信息的结构:
<type>[optional scope]: <subject>
[optional body]
[optional footer(s)]
其中:
type(必填):如 feat、fix,用于分类
scope(可选):如 core、ui,用于描述影响范围
!(可选):表示破坏性变更
subject(必填):简短描述本次变更
body(可选):详细说明
footer(可选):如 BREAKING CHANGE、Closes #123
gitru 就是基于此规范实现的,并允许你通过配置文件进行自定义。
📦 安装 gitru
你可以通过三种方式安装:
方式一:直接下载二进制文件(推荐)
前往👉 GitHub Releases
下载对应平台的压缩包,解压后:
放到任意目录
加入 PATH
Linux / macOS 可能需要执行权限
方式二:通过 cargo 安装(需 Rust 环境)
cargo install gitru
方式三:本地编译
git clone https://github.com/xiyixiaodao/gitru.git
cd gitru
cargo install --path .
验证安装:
gitru --version
🛠 使用方法
一键初始化
以下命令会同时安装 Hook 并生成配置文件:
gitru ii commit-msg
它等价于:
gitru install commit-msg
gitru init commit-msg
如果文件已存在,可强制覆盖:
gitru ii commit-msg -f
卸载 Hook
gitru uninstall commit-msg
然后手动删除 .commit-msg-rule.toml。
⚙️ 自定义校验规则
gitru 的核心是配置文件 .commit-msg-rule.toml。
你只需要修改它,就能完全定制校验逻辑。
为什么选择 TOML 而不是 YAML?
YAML 结构依赖缩进,容易错位
.yaml / .yml 后缀容易混淆
TOML 更简单、可读性更强
对新手更友好
即使你不懂 TOML,也完全不影响使用。
📄 配置文件示例
下面是 gitru 初始化后生成的配置文件(部分注释已去除):
# ╔═════════════════════════════════════════════════╗
# ║ COMMIT FORMAT TEMPLATE ║
# ╠═════════════════════════════════════════════════╣
# ║ type(optional scope): subject ║
# ║ ║
# ║ [optional body] ║
# ║ ║
# ║ [optional footer] ║
# ║ - BREAKING CHANGE: xxxxx ║
# ║ - Closes #issue ║
# ╚═════════════════════════════════════════════════╝
[global]
version = "1.0.0"
enable_validation = true
skip_validation_words = ["--no-verify", "SKIP"]
[header.type]
allowed_types = ["feat", "fix", "docs", "style", "refactor", "test", "chore", "ci"]
[header.scope]
required = false
allowed_scopes = ["core", "cli", "ui", "docs", "test"]
[header.subject]
spaces_after_colon = 1
forbid_trailing_period = true
min_length = 2
max_length = 72
[body]
required = false
min_blank_lines_before_body = 1
forbid_trailing_whitespace = true
min_line_length = 2
max_line_length = 72
[footer]
start_key_words = ["BREAKING CHANGE", "Closes", "Fixes", "Signed-off-by"]
min_blank_lines_before_footer = 1
min_line_length = 2
max_line_length = 72
forbid_trailing_whitespace = true
[footer.start_key_words_spellcheck]
enable = true
threshold = 0.7
🔍 配置项详解
下面对关键配置项进行说明(按模块划分)。
1. 全局配置(global)
控制 gitru 的整体行为:
[global]
version = "1.0.0"
enable_validation = true
skip_validation_words = ["--no-verify", "SKIP"]
version: 用于以后大版本变更升级区分,当前没有区别。
enable_validation:是否启用校验
skip_validation_words:提交信息第一行完全匹配时跳过校验
2. Header 校验
Header 是最重要的部分,包含:
type(scope): subject
2.1 type 校验
[header.type]
allowed_types = ["feat", "fix", "docs", "style", "refactor", "test", "chore", "ci"]
避免出现 update、tmp、aaa 等无意义 type
让团队提交类型统一
让 changelog 自动生成更准确
⚠ 不允许为空数组
若不需要 type 校验,请注释掉整个字段。
提交示例:
校验通过:
feat: add login API
校验失败:
#错误示例1
update: change UI layout
#提示
error: commit type `update` is not in the allowed list, allowed types are ["feat", "fix", "docs", "style", "refactor", "test", "chore", "ci"]
#错误示例2
feats: add login API
#提示
error: unknown commit type `feats`
help: did you mean `feat`? (similarity 0.80)
note: allowed types: ["feat", "fix", "docs", "style", "refactor", "test", "chore", "ci"]
2.2 scope 校验
[header.scope]
required = false
allowed_scopes = ["core", "cli", "ui", "docs", "test"]
required = true → 必须提供 scope
required = false → 可选
若提供 scope,必须在 allowed_scopes 中
⚠ allowed_scopes 不允许为空数组,若不需要校验,请注释掉整个字段。
2.3 subject 校验
[header.subject]
spaces_after_colon = 1
forbid_trailing_period = true
min_length = 2
max_length = 72
限制冒号后空格数量(默认为推荐的1个,建议不要修改)
禁止句号结尾(包含英文句号和中文句号)
限制 subject 长度
3. Body 校验
[body]
required = false
min_blank_lines_before_body = 1
forbid_trailing_whitespace = true
min_line_length = 2
max_line_length = 72
默认可选
body和header之间的空行数量(不建议修改)
禁止行尾出现多余空格
限制 body每一行的长度
4. Footer 校验
[footer]
start_key_words = ["BREAKING CHANGE", "Closes", "Fixes", "Signed-off-by"]
footer部分的起始关键字
支持关键字拼写检查:
[footer.start_key_words_spellcheck]
enable = true
threshold = 0.7
提交示例:
feat: test footer
Close: #123
错误提示:
error: footer keyword appears misspelled:
"Close" → "Closes"
similarity = 0.83 (threshold = 0.70)
⭐ gitru 的两大特色能力
1. 跳过校验(Skip Validation)
虽然提交信息规范非常重要,但在实际开发中,总会遇到一些必须绕过校验的场景,这些提交往往不需要遵循团队的 commit 规范,甚至无法遵循。
因此,gitru 必须提供一种 安全、明确、可控 的方式来跳过校验。
在 Git 生态中,常见的跳过校验方式有三种:
① 命令行参数:git commit --no-verify
Git 原生支持:
git commit --no-verify
它会跳过所有 Hook,包括:
commit-msg
pre-commit
prepare-commit-msg
post-commit
② IDE 设置跳过 Hook
例如:
JetBrains 系列(IDEA / PyCharm / RustRover)
VSCode
不同IDE的设置不一致,有的需要设置中默认开启才会有对应操作,比如VSCode;有的选择跳过后如果忘记手动选回来,后续校验也会继续跳过。
③ gitru 的方式:提交信息首行关键字
gitru 允许通过提交信息第一行完全匹配关键字来跳过校验:
注意:关键字可在配置文件中配置,但是严格区分大小写(当然,如果只是大小写不一致会有报错信息准确提示)
示例:
SKIP
fix: hotfix production issue
或:
--no-verify
feat: auto commit from script
默认配置下,以上提交都会直接跳过所有校验,并且在最终生成的校验信息中去除首行关键字。
2. 拼写检测(Spell Check)
由于规范约定缘故,body可选,中间可有空行,footer也是可选的,所以很难区分二者。gitru采用了footer配置关键字来区分。
这样一来footer校验严重依赖用户输入的单词,而人是最靠不住的,所以尽可能做点保障,校验用户是否拼写错误。
检测 footer 关键字是否拼写错误
避免 Clsoe、Fixex 这种低级错误导致自动化流程失效
使用相似度算法(默认阈值 0.7)
当检测到疑似拼写错误时,会阻止提交并给出友好提示
如果用户确认自己没错,就可以使用上一步提供的方法跳过校验强制提交。
footer提取关键字依赖:分割。
由于footer部分自由度太高,目前没想到完美的校验方法,好在我们大部分时间用到的是header和body校验。
🎉 总结
gitru 的目标不是取代现有工具,而是提供一个:
更轻量
更简单
更易安装
更适合非 Node/Python 项目
的 commit-msg 校验方案。
如果你在使用过程中有任何建议或问题,欢迎在 GitHub 提 issue,一起让这个小工具变得更好。
