当前位置: 首页 > news >正文

基于Git Hook的代码质量防线:Commit前自动格式化+静态扫描

有时候真不是大家不想写好代码,实在是手一快就忘了格式化,或者临提交才发现缩进一团糟。Review时满屏的空白字符变更比逻辑改动还多,那个心情,血压直接飙到 180。

后来我们在项目里加了一道防线:利用 Git Hook,在 commit 之前自动做格式化和静态扫描,不通过直接不给提交。这事做下来,整个代码库干净多了,PR 里再也没有“格式化战争”。下面分享一份我们正在用的 pre-commit 脚本,以及借助 lint-staged 的更优雅玩法。

裸装的 pre-commit 钩子

最早我们是直接在 .git/hooks/pre-commit 里塞一个脚本,让 Git 在提交前强制跑检查。简单粗暴,不依赖第三方工具。脚本长这样:

#!/bin/bash
# .git/hooks/pre-commit# 获取所有暂存区中新增或修改的文件(不包含删除)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)if [ -z "$STAGED_FILES" ]; thenecho "没有暂存文件,允许提交"exit 0
fiecho "==================== 代码格式检查 ===================="
# 先跑 Prettier 格式化,这里只检查不直接修改(如果你想让脚本帮你改,可以去掉--check)
FORMAT_ERROR=0
while IFS= read -r FILE; do# 只处理 JavaScript/TypeScript 文件,防止误伤if [[ "$FILE" =~ \.(js|jsx|ts|tsx)$ ]]; thennpx prettier --check "$FILE" --config .prettierrc 2>/dev/nullif [ $? -ne 0 ]; thenecho "❌ $FILE 格式不规范,请先执行 prettier --write 再提交"FORMAT_ERROR=1fifi
done <<< "$STAGED_FILES"if [ $FORMAT_ERROR -ne 0 ]; thenecho ">> 格式化检查未通过,提交中止"exit 1
fiecho "==================== 静态扫描 ===================="
# 再跑 ESLint
LINT_ERROR=0
while IFS= read -r FILE; doif [[ "$FILE" =~ \.(js|jsx|ts|tsx)$ ]]; thennpx eslint --quiet "$FILE" --config .eslintrc.js 2>/dev/nullif [ $? -ne 0 ]; thenLINT_ERROR=1fifi
done <<< "$STAGED_FILES"if [ $LINT_ERROR -ne 0 ]; thenecho ">> 静态扫描发现错误,提交中止"exit 1
fiecho "✅ 所有检查通过,允许提交"
exit 0

解释几个容易踩坑的点:

  • git diff --cached --name-only --diff-filter=ACMR 只拿暂存区里新增 (A)、复制 (C)、修改 (M)、重命名 (R) 的文件,避免去检查已经删除的文件导致报错。
  • 循环里用 2>/dev/null 把一些恼人的内部输出吞掉,只保留关键信息。
  • Prettier 我用 --check 而不是直接 --write,因为我不喜欢 Hook 偷偷改文件内容,万一格式变化和逻辑修改混在一起,回滚很麻烦。团队习惯是让开发者自己跑一次修复命令再重新提交,责任清晰。

这个脚本有个明显的缺点:对大项目比较慢,因为每次提交都会全量检查所有暂存文件。而且如果只是想快速提交一个 hotfix,它也会强制跑一遍。所以后来我们上了 lint-staged。

进阶版:lint-staged + husky

与其手写循环,不如把活儿交给 lint-staged,它只对被 staged 的文件执行指定命令,快且配置清晰。

安装 husky 和 lint-staged:

npm install husky lint-staged --save-dev
npx husky install

然后在 package.json 里配置:

"lint-staged": {"*.{js,jsx,ts,tsx}": ["prettier --check","eslint --quiet"],"*.{json,md,css}": ["prettier --check"]
}

接着用 husky 接管 pre-commit 钩子:

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

生成的 .husky/pre-commit 就这么一行:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"npx lint-staged

这种方式的亮点在哪?

  • 只跑受影响的文件,大仓也不怕慢。
  • 配置文件集中管理,新成员克隆项目后 npm install 就自动启用 hook,不用再去手动拷贝 .git/hooks
  • 扩展性强,后期加 stylelint、commitlint 只需要往 lint-staged 里追加命令。

不过有个小问题:prettier --check 失败只会报错不自动修,如果你更喜欢“提交时自动格式化”,可以把命令改成 prettier --write。但这样会导致文件被修改后需要重新 add,如果没注意可能会漏掉改动。我们的折中方案是:报错后提醒开发者跑一次格式化命令,再重新提交。钩子不做隐式修改。

效果与感受

上了这套之后,代码风格问题直接被拦在本地,CI 再也不用浪费时间去跑格式检查。Review 时只看逻辑改动,清爽多了。偶尔有新同事抱怨“怎么提交不了”,告诉他先跑一下 lint 就好了,习惯之后都觉得很顺。

当然,这套防线不能解决所有质量问题,比如单元测试覆盖率、复杂度控制,还得靠 CI 来做。但至少在编码风格这一关,不用再跟同事拉扯了。

如果你还没在项目里用 Git Hook 做质量门禁,强烈建议试试。不想自己写脚本就直接上 husky + lint-staged,五分钟配完,长期受益。

http://www.jsqmd.com/news/962576/

相关文章:

  • SideJITServer:iOS 17无线JIT编译的终极解决方案
  • uesave:5分钟掌握虚幻引擎游戏存档编辑,解锁无限游戏可能
  • OpenRocket火箭仿真软件:开源模型火箭设计与飞行分析技术工具
  • 3分钟搞定!Mac用户的Windows启动盘制作终极指南:WinDiskWriter完全教程
  • Sketch MeaXure:设计师必备的智能标注插件,让设计交付效率提升300%
  • 2026甄选:江西电大中专报名与成人高考函授报考正规品牌机构解析 - 品牌企业推荐师(官方)
  • 鸿蒙 App 集成 AI 助手:架构设计 + 实战代码
  • 2026无锡黄金回收权威行情解读,龙头品牌领先实操攻略 - 奢侈品回收评测
  • 如何永久保存微信聊天记录:WeChatMsg完整备份与导出指南
  • 【实战|附源码】PHP搭建DCS分布式控制系统:工业监控后台完整实现方案
  • 网盘直链下载助手LinkSwift:免费获取九大网盘真实下载地址的终极指南
  • Video2X 6.0.0:免费AI视频放大神器,让模糊视频重获新生
  • 如何快速上手Flashtool:索尼Xperia设备刷机终极指南
  • Arduino CNC运动控制固件包:GRBL源码+编译配置+全功能模块
  • 3分钟搞定AI视频创作:Auto-Video-Generator终极快速上手指南
  • Simple Live终极指南:跨平台直播聚合应用,一站式观看所有热门直播
  • 实战应用:基于快马平台构建企业级西电b测解决方案
  • 从《西游记》看技术团队管理:唐僧为何是领导?
  • 3D打印切片终极指南:如何用Slic3r轻松将创意变为现实 [特殊字符]
  • 晶振电路电阻选型:从巴克豪森准则到实战调试的深度解析
  • 3层架构深度优化:Win11Debloat如何重构Windows 11用户体验
  • 安卓虚拟摄像头终极配置指南:5分钟快速上手Xposed模块
  • 半导体成本解析与代理商谈判实战:从PN结到芯片价格的工程师指南
  • next-images插件生态扩展:与其他Next.js插件集成方案
  • 实战应用:基于快马平台开发简历word文档关键信息自动解析系统
  • Himalaya源码解析:深入理解Lexer与Parser模块的工作原理
  • SpeechScore:开源语音质量评估工具的终极指南
  • 深圳家庭教育指导师报名机构哪家好?正规授权机构推荐:中山优才教育 - 当下教育培训干货
  • 瑞祥商联卡没用完怎么办?实用回收处理方法参考 - 圆圆收
  • 深度解析AI自瞄系统:基于YOLOv8/YOLOv10的FPS游戏智能瞄准解决方案