在团队协作开发中,保持代码风格的一致性至关重要。Git 钩子(Git Hooks)提供了一种在特定事件(如提交、推送)发生时自动执行脚本的机制。其中,pre-commit 钩子是在提交(commit)操作实际发生前运行的,它是执行代码格式化和静态分析的最佳时机。
虽然可以直接在 .git/hooks/pre-commit 中编写 Shell 脚本,但我们推荐使用强大的第三方工具 pre-commit 框架。它提供了一个跨语言、易于配置、便于管理钩子依赖的环境。
1. 安装 pre-commit 框架
pre-commit 工具本身是基于 Python 的,但它可以管理任何语言的钩子。
首先,确保您的环境中安装了 Python 和 pip,然后执行安装命令:
pip install pre-commit
对于 macOS 用户,也可以使用 Homebrew:
brew install pre-commit
2. 配置 Git 钩子
pre-commit 框架通过项目根目录下的配置文件 .pre-commit-config.yaml 来定义要运行哪些检查器(Hooks)。
我们以一个常见的 Python 项目为例,配置 black (代码格式化) 和 isort (导入排序) 钩子,并添加一个通用的检查器来去除行尾空格。
创建 .pre-commit-config.yaml 文件并添加以下内容:
# .pre-commit-config.yaml
repos:
# 检查并去除文件末尾的空白字符和文件末尾的新行
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
# Python 格式化工具 Black
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
language_version: python3.11 # 指定Python版本
# Python 导入语句排序工具 Isort
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
args: ['--profile', 'black'] # 兼容 black 的配置
注意: rev 字段指定了钩子仓库的版本,建议使用稳定版本。
3. 安装 Hooks 到 Git 仓库
配置文件定义了要运行的检查,但我们还需要将 pre-commit 框架安装到当前 Git 仓库的 .git/hooks/pre-commit 文件中。
在项目根目录下执行:
pre-commit install
安装成功后,每次执行 git commit 时,该脚本都会自动运行。
4. 运行与测试
当您第一次运行提交时,pre-commit 会自动下载并构建 .pre-commit-config.yaml 中指定的依赖环境(这些环境默认保存在本地缓存中,不会污染您的项目环境)。
示例:测试自动修复
创建一个故意格式错误且导入混乱的 Python 文件 test.py:
# test.py
import os, sys
def my_func ( a , b ) :
return a+b
尝试提交该文件:
git add test.py
git commit -m "Testing auto-fix hooks"
观察输出:
- pre-commit 脚本会被触发。
- trailing-whitespace 会清理行尾空格。
- isort 会重新排序导入语句。
- black 会将函数格式化为符合规范。
如果钩子发现并自动修复了问题(如 black 或 isort),它会中止当前的提交,并提示:Files were modified by the hooks. Re-stage and commit.
此时,test.py 文件已经被格式化:
# test.py
import os
import sys
def my_func(a, b):
return a + b
您只需再次执行 git add test.py 和 git commit 即可完成提交。这次检查会顺利通过,因为文件已经是干净的了。
绕过钩子
如果您在极少数情况下需要绕过所有 pre-commit 钩子,可以在提交时使用 –no-verify 标志:
git commit -m "Emergency commit" --no-verify
汤不热吧