如何使用 Git hooks 实现提交前自动代码格式化

文章导读
在 JavaScript 或 TypeScript 项目中,最推荐通过 husky 配合 lint-staged 实现提交前自动格式化;通用项目可直接编写 Git pre-commit 脚本。适用场景为本地开发环境约束,风险边界在于钩子仅作用于本地,不能替代服务端 CI 检查。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

在 JavaScript 或 TypeScript 项目中,最推荐通过 husky 配合 lint-staged 实现提交前自动格式化;通用项目可直接编写 Git pre-commit 脚本。适用场景为本地开发环境约束,风险边界在于钩子仅作用于本地,不能替代服务端 CI 检查。

先说结论:本地 Git Hooks 能有效阻止不符合格式规范的代码进入仓库,但必须配合 CI 流程双重验证。

  • 适合:团队统一代码风格、减少 Code Review 中格式类评论的场景。
  • 先准备:确认项目依赖的格式化工具(如 Prettier、Black、gofmt)已可独立运行。
  • 验收:故意制造格式错误并提交,验证钩子是否自动修复或阻断提交。

命令速用版

以下命令适用于 Node.js 项目快速接入 Husky 和 lint-staged:

npm install -D husky lint-staged
npx husky install
npm pkg set scripts.prepare="husky install"
npx husky add .husky/pre-commit "npx lint-staged"

为什么会这样

Git Hooks 是 Git 在特定事件(如提交、推送)发生时自动执行的脚本。

通过 pre-commit 钩子拦截提交动作,可以在代码写入本地仓库前强制运行格式化工具。这样做能避免格式问题污染提交历史,减少团队成员间因缩进、引号等风格产生的争议。但钩子运行在开发者本地机器,若本地环境与 CI 环境不一致,仍可能出现提交后构建失败的情况。

分步处理

步骤 1:安装依赖工具

确保项目已安装格式化工具。以 Prettier 为例,执行安装命令并生成配置文件:

npm install -D prettier
echo {} > .prettierrc

步骤 2:配置 Git 钩子管理工具

使用 Husky 管理钩子脚本,避免直接编辑 .git/hooks 目录导致版本控制丢失。初始化 Husky 并配置 prepare 脚本,确保克隆仓库后自动安装钩子:

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

步骤 3:编写预提交检查逻辑

添加 pre-commit 钩子,调用 lint-staged 仅检查暂存区文件,避免全量检查耗时过长:

npx husky add .husky/pre-commit "npx lint-staged"

在 package.json 中配置 lint-staged 规则,指定文件类型对应的格式化命令:

如何使用 Git hooks 实现提交前自动代码格式化
"lint-staged": {
  "*.{js,ts,jsx,tsx}": ["prettier `--write`"]
}

步骤 4:提交钩子脚本到版本控制

将 .husky 目录加入 Git 跟踪,确保团队成员拉取代码后拥有相同的钩子配置:

git add .husky
git commit -m "chore: add husky hooks"

怎么验证是否生效

修改一个已跟踪的 JavaScript 文件,故意删除分号或破坏缩进。执行 git add 将该文件加入暂存区,然后运行 git commit。

若配置生效,终端应显示 Prettier 正在格式化文件,且提交成功后代码恢复规范格式。若格式化失败或配置错误,提交动作应被中断并报错。

常见坑

CI 与本地环境不一致:本地钩子成功不代表 CI 通过。必须在 CI 流程中再次运行格式化检查命令,且配置参数需与本地完全一致。

Windows 换行符问题:跨平台开发时,Git 可能自动转换换行符(CRLF/LF),导致格式化工具误判文件变动。建议在仓库根目录添加 .gitattributes 强制统一换行符。

钩子执行耗时过长:若全量检查大型项目,提交会变慢。务必使用 lint-staged 等工具限制只检查本次提交涉及的文件。

常见问题

如何临时跳过 Git Hooks 提交?

在 commit 命令后添加 `--no-verify` 参数可跳过钩子检查,例如 git commit -m "msg" `--no-verify`。仅建议在紧急修复或钩子配置错误时使用,常规开发不应跳过。

配置了 Hooks 还需要 CI 检查吗?

需要。Git Hooks 运行在本地,可能被用户跳过或配置不一致。CI 检查是代码合并前的最后一道防线,必须保留。

为什么克隆仓库后钩子不生效?

Git 默认不跟踪 .git/hooks 目录。使用 Husky 等工具将钩子脚本放在项目根目录并通过 prepare 脚本自动安装,可解决此问题。

参考来源

  • Git Documentation, "Git Hooks", https://git-scm.com/docs/githooks
  • Husky Documentation, "Getting Started", https://typicode.github.io/husky/
  • Prettier Documentation, "Pre-commit Hook", https://prettier.io/docs/en/precommit.html