跳转至

626 pre-commit 代码质量钩子

一句话概述:pre-commit 是 Git 钩子管理工具,在你提交代码前自动运行检查(格式化、语法检查、安全扫描),把问题挡在代码进入仓库之前,是团队代码质量的"守门员"。

核心知识点速查表

知识点说明
最新版本pre-commit v6.0.0+(2026年)
核心功能Git commit 前自动运行代码检查和格式化
支持语言Python、JavaScript、Go、Rust、Shell 等全语言
配置文件.pre-commit-config.yaml
2026趋势Ruff 替代 Black/Flake8/isort,成为 Python 检查主流
适用场景个人项目、团队协作、CI/CD

一、安装配置

# 安装 pre-commit
pip install pre-commit                 # Python 安装
# 或
brew install pre-commit                # macOS
# 或
conda install -c conda-forge pre-commit  # Conda

# 验证安装
pre-commit --version                   # 输出:pre-commit 6.x.x

1.1 初始化项目

# 在 Git 项目根目录下
pre-commit install                     # 安装 Git 钩子(在 .git/hooks/ 下创建 pre-commit)
# 白话:安装后,每次 git commit 会自动运行检查

# 可选:安装其他阶段的钩子
pre-commit install --hook-type commit-msg    # commit 消息检查
pre-commit install --hook-type pre-push      # push 前检查

二、基本使用

2.1 配置文件

# .pre-commit-config.yaml(项目根目录)
repos:
  # ---- 通用检查(所有项目都应该有) ----
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0                        # 使用的版本(固定版本号)
    hooks:
      - id: trailing-whitespace        # 删除行尾空格
      - id: end-of-file-fixer          # 确保文件以换行符结尾
      - id: check-yaml                 # 检查 YAML 语法
      - id: check-json                 # 检查 JSON 语法
      - id: check-toml                 # 检查 TOML 语法
      - id: check-added-large-files    # 防止提交大文件(默认 > 500KB)
        args: ['--maxkb=1000']         # 自定义阈值:1MB
      - id: check-merge-conflict       # 检查是否遗留合并冲突标记
      - id: detect-private-key         # 检测是否意外提交私钥
      - id: check-case-conflict        # 检查文件名大小写冲突

  # ---- Python 代码检查(Ruff:一个工具替代 Black + Flake8 + isort) ----
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.11.0
    hooks:
      - id: ruff                       # 代码检查(替代 Flake8 + isort)
        args: [--fix]                  # 自动修复可修复的问题
      - id: ruff-format                # 代码格式化(替代 Black)
        # 白话:Ruff 用 Rust 写的,比 Black+Flake8 快 100 倍

  # ---- 安全检查(检测密钥泄露) ----
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.0
    hooks:
      - id: gitleaks                   # 扫描代码中的密钥、密码、Token
        # 白话:防止你不小心把 API Key 提交到 Git

2.2 常用命令

# 手动运行(不需要 commit)
pre-commit run --all-files             # 对所有文件运行检查
pre-commit run --files src/main.py     # 只检查指定文件
pre-commit run ruff --all-files        # 只运行 ruff 检查

# 更新钩子版本
pre-commit autoupdate                  # 自动更新所有钩子到最新版本

# 跳过钩子(紧急情况)
git commit --no-verify -m "紧急修复"    # 跳过所有钩子(慎用!)
# 或
SKIP=ruff git commit -m "跳过ruff"     # 只跳过特定钩子

# 清理缓存
pre-commit clean                       # 清理钩子环境缓存
pre-commit gc                          # 垃圾回收

三、各语言配置模板

3.1 Python 项目(推荐配置)

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-added-large-files
      - id: detect-private-key

  # Ruff(一站式 Python 代码质量工具)
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.11.0
    hooks:
      - id: ruff
        args: [--fix, --select, "E,F,I,UP,N,B"]  # 启用多种规则
        # E=pycodestyle, F=pyflakes, I=isort, UP=pyupgrade, N=pep8-naming, B=bugbear
      - id: ruff-format

  # 类型检查
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.15.0
    hooks:
      - id: mypy                       # Python 静态类型检查
        additional_dependencies:       # mypy 需要的额外依赖
          - types-requests

  # 安全检查
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.0
    hooks:
      - id: gitleaks

3.2 JavaScript/TypeScript 项目

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-json
      - id: check-added-large-files

  # ESLint(JS/TS 代码检查)
  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v9.20.0
    hooks:
      - id: eslint
        files: \.[jt]sx?$              # 匹配 .js .jsx .ts .tsx 文件
        types: [file]
        additional_dependencies:
          - eslint@9
          - typescript

  # Prettier(格式化)
  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v4.0.0
    hooks:
      - id: prettier
        types_or: [javascript, typescript, json, yaml, markdown, css]

3.3 通用项目(多语言)

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-json
      - id: check-toml
      - id: check-added-large-files
      - id: check-merge-conflict
      - id: detect-private-key
      - id: mixed-line-ending           # 统一换行符
        args: ['--fix=lf']             # 统一为 LF(Unix 风格)

  # Shell 脚本检查
  - repo: https://github.com/shellcheck-py/shellcheck-py
    rev: v0.10.0
    hooks:
      - id: shellcheck                 # Shell 脚本静态分析

  # Markdown 检查
  - repo: https://github.com/igorshubovych/markdownlint-cli
    rev: v0.44.0
    hooks:
      - id: markdownlint               # Markdown 格式检查
        args: ['--fix']                # 自动修复

  # Dockerfile 检查
  - repo: https://github.com/hadolint/hadolint
    rev: v2.12.0
    hooks:
      - id: hadolint                   # Dockerfile 最佳实践检查

  # 密钥泄露检查
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.0
    hooks:
      - id: gitleaks

四、高级用法

4.1 自定义本地钩子

repos:
  # 本地自定义钩子(不需要从远程仓库拉取)
  - repo: local
    hooks:
      - id: pytest-check               # 自定义 ID
        name: 运行 pytest 测试          # 显示名称
        entry: pytest tests/ -x        # 要执行的命令
        language: system               # 使用系统已安装的工具
        pass_filenames: false          # 不传文件名给命令
        always_run: true               # 每次 commit 都运行
        stages: [pre-commit]           # 在 pre-commit 阶段运行

      - id: check-todo
        name: 检查 TODO 注释
        entry: bash -c 'grep -rn "TODO\|FIXME\|HACK" --include="*.py" src/ && exit 1 || exit 0'
        language: system
        pass_filenames: false

4.2 Commit 消息检查

repos:
  # commitlint:检查 commit 消息格式
  - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
    rev: v9.18.0
    hooks:
      - id: commitlint
        stages: [commit-msg]           # 在 commit-msg 阶段运行
        additional_dependencies:
          - '@commitlint/config-conventional'
        # 白话:强制 commit 消息格式为 "feat: xxx" / "fix: xxx" 等
# 安装 commit-msg 钩子
pre-commit install --hook-type commit-msg

4.3 CI 中使用 pre-commit

# .github/workflows/pre-commit.yml
name: pre-commit 检查

on: [push, pull_request]

jobs:
  pre-commit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - uses: pre-commit/action@v3.0.1  # 官方 GitHub Action
        # 白话:在 CI 中也运行 pre-commit,防止有人跳过本地钩子

4.4 排除文件和目录

repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.11.0
    hooks:
      - id: ruff
        exclude: |                     # 排除的文件/目录(正则表达式)
          (?x)^(
            migrations/.*|             # 排除数据库迁移文件
            vendor/.*|                 # 排除第三方代码
            .*_generated\.py           # 排除自动生成的文件
          )$
        args: [--fix]

  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: trailing-whitespace
        exclude: \.md$                 # Markdown 文件不删尾部空格

五、常见报错与解决

问题解决
hook failed 后提交失败查看输出,修复问题后重新 git addgit commit
ruff 自动修复了文件文件已被修改,git add 重新暂存后再提交
钩子运行太慢用 Ruff 替代 Black+Flake8(快 100 倍);或减少 --all-files
pre-commit install 没效果检查是否在 Git 仓库根目录运行
版本冲突运行 pre-commit autoupdate 更新到最新版

六、速查表

操作命令
安装pip install pre-commit
初始化钩子pre-commit install
运行全部检查pre-commit run --all-files
运行单个钩子pre-commit run 钩子ID --all-files
更新钩子版本pre-commit autoupdate
跳过钩子提交git commit --no-verify
跳过特定钩子SKIP=钩子ID git commit
清理缓存pre-commit clean
安装消息钩子pre-commit install --hook-type commit-msg
CI 中运行uses: pre-commit/action@v3.0.1

七、同类工具对比

特性pre-commitHusky (JS)Lefthooklint-staged
语言PythonNode.jsGoNode.js
多语言支持所有JS/TS为主所有JS/TS为主
配置方式YAMLJSON/JSYAMLJSON
钩子生态极丰富npm 生态增长中无(搭配用)
性能良好良好极快良好
适合场景通用Node项目通用搭配 Husky

选型建议:Python 项目或多语言项目首选 pre-commit(生态最完善);纯 Node.js 项目可用 Husky + lint-staged;追求极速选 Lefthook。


参考资料pre-commit 官方文档 | GitHub | 支持的 Hooks 列表