Git Hooks的pre-commit脚本可实现本地代码语法校验与自动格式化:一、启用并编写含set -e/-u的Shell脚本;二、用git diff --cached筛选待提交文件,调用flake8/eslint等检查;三、用prettier/black修复后git add回暂存区;四、支持跳过校验、清晰报错及多语言分发处理,并建议符号链接共享脚本。
在代码提交前自动进行语法校验与格式化,能显著提升团队代码质量并减少人工干预。Git Hooks(特别是
)配合 Shell 脚本是最轻量、最可控的实现方式,无需引入复杂 CI 工具即可在本地拦截问题。
一、启用 pre-commit Hook 并编写基础 Shell 脚本
Git 的
是一个可执行脚本,在每次
前自动运行。它默认是 shell 脚本,只需确保有执行权限:
进入项目根目录,执行:
若无该文件,新建并编辑:
脚本开头必须包含
,并建议添加
(出错即退出)和
(未定义变量报错)增强健壮性
二、校验:用 linters 检查暂存区中待提交的代码
只检查将要提交的文件(即
输出),避免全量扫描拖慢提交流程。以 Python 和 JavaScript 为例:
Python:用
或
,例如:
JavaScript:用
,例如:
(
仅报告可修复项,不实际修改)
关键点:用
只捕获新增(A)、已修改(M)、重命名后内容变更(C)的文件,跳过删除或未变更文件
三、格式化:自动修复并重新暂存,保持提交原子性
若检测到可自动修复的问题(如 Prettier、Black),应在 hook 中完成格式化并
回暂存区,否则 commit 会因未暂存修改而失败:
CentOS Linux 7.9.2009
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离线兼容性测试。
下载
示例(JS):
示例(Python):
注意:格式化命令需支持静默模式(如
)避免干扰输出;
必须显式指定文件,不能用
,防止误提交未暂存的其他改动
四、增强体验:跳过校验、提示友好错误、支持多语言混合项目
生产级 hook 需兼顾开发效率与约束力:
支持临时跳过:
或在脚本开头判断
(但更推荐用环境变量如
)
错误提示清晰:对每类文件分别运行检查,失败时打印具体文件名和错误摘要,避免“脚本退出码 1”这类模糊信息
按后缀分发处理逻辑:用
语句匹配
、
、
、
等,调用对应工具,避免单个工具缺失导致整个 hook 失败(可用
)
不复杂但容易忽略:hook 是本地行为,无法强制他人使用;建议将脚本纳入项目仓库(如
),再通过
符号链接,并在 README 中说明初始化方式,让新成员一键启用。
pre-commit.git/hooks/pre-commitgit commitchmod +x .git/hooks/pre-committouch .git/hooks/pre-commit && vim .git/hooks/pre-commit#!/bin/bashset -eset -ugit diff --cached --name-onlypylintflake8git diff --cached --name-only --diff-filter=ACM | grep '\.py$' | xargs -r flake8 --max-line-length=88eslintgit diff --cached --name-only --diff-filter=ACM | grep '\.js$' | xargs -r eslint --quiet --fix-dry-run--fix-dry-run--diff-filter=ACMgit addgit diff --cached --name-only --diff-filter=ACM | grep '\.js$' | xargs -r prettier --write && git add $(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')git diff --cached --name-only --diff-filter=ACM | grep '\.py$' | xargs -r black --quiet && git add $(git diff --cached --name-only --diff-filter=ACM | grep '\.py$')--quietgit addgit add .git commit --no-verifyif [[ "$1" == "--no-verify" ]]; then exit 0; fiSKIP_LINT=1 git commitcase.py.js.ts.mdcommand -v xxx && xxx ... || echo "xxx not found, skip"scripts/pre-commitln -sf ../scripts/pre-commit .git/hooks/pre-commit