本文档已迁移至 pre-commit/README.md。本文档不再更新。

pre-commit 落地指南

← 返回目录 > ← 返回总览

方案概述

pre-commit 是一个跨语言的 Git 钩子管理框架,通过 .pre-commit-config.yaml 统一声明、安装和执行来自不同语言生态的检查工具。本文档聚焦"怎么配、怎么用、怎么拦截、怎么屏蔽"的工程实践,覆盖本地提交前检查、PR 门禁拦截、CI/CD 集成、告警处理与屏蔽、PR 自动修复等核心场景,并在各场景中区分 GitCode 和 GitHub 平台的差异;安装方式、配置字段、命令行接口等参考信息见 pre-commit 工具详解。

核心价值

  • 统一入口:通过一份 .pre-commit-config.yaml 统一调度所有语言的检查工具,本地和 CI 复用同一份配置
  • 增量检查:默认只检查暂存区变更文件,本地提交秒级反馈,CI 中可按 PR 变更文件检查
  • 版本锁定:通过 rev 字段锁定每个 hook 的版本,保证团队一致性
  • 依赖隔离:自动为每个 hook 创建独立虚拟环境,不污染项目本地依赖

适用场景

场景 本文章节
开发者本地提交前自动检查 本地提交前检查
PR 门禁拦截不合规代码 PR 门禁检查
遇到告警需要处理或屏蔽 告警处理与屏蔽
PR 上自动修复格式问题 在 PR 中使用 pre-commit 自动修复代码

本地提交前检查

工作流程

flowchart TD
    A[项目根目录配置 .pre-commit-config.yaml] --> B[安装 pre-commit 并执行 pre-commit install]
    B --> C[git commit 触发 pre-commit]
    C --> D[按配置下载并运行所有 hook\n仅检查暂存区变更文件]
    D --> E{检查结果}
    E -->|全部通过| F[提交成功]
    E -->|任一 hook 失败| G[提交中止并提示错误]
    G --> H[根据提示修复问题]
    H --> C

步骤 1:编写配置文件

在项目根目录创建 .pre-commit-config.yaml。以下是覆盖通用基础检查、密钥检测、拼写检查和多语言工具的推荐配置:

# .pre-commit-config.yaml
minimum_pre_commit_version: "4.0"

repos:
  # ===================== 通用基础钩子(所有语言) =====================
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace # 移除行尾空白字符
      - id: end-of-file-fixer # 确保文件以换行符结尾
      - id: check-yaml # 校验 YAML 文件语法
      - id: check-json # 校验 JSON 文件语法
      - id: check-xml # 校验 XML 文件语法
      - id: check-merge-conflict # 检查未解决的合并冲突标记
      - id: check-added-large-files # 拦截超大文件提交(默认 500KB)
      - id: detect-private-key # 检测私钥文件

  # ===================== 密钥检测 =====================
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.21.2
    hooks:
      - id: gitleaks

  # ===================== 拼写检查 =====================
  - repo: https://github.com/codespell-project/codespell
    rev: v2.4.2
    hooks:
      - id: codespell

  # ===================== Python =====================
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.15.17
    hooks:
      - id: ruff-check
        args: [--fix]
      - id: ruff-format

  # ===================== Shell =====================
  - repo: https://github.com/shellcheck-py/shellcheck-py
    rev: v0.11.0.1
    hooks:
      - id: shellcheck
        args: [--severity=warning]

  # ===================== Markdown =====================
  - repo: https://github.com/igorshubovych/markdownlint-cli
    rev: v0.45.0
    hooks:
      - id: markdownlint
        args: [--fix]

各语言工具的详细配置和选型建议,参考对应 语言指南。

步骤 2:安装 pre-commit

# pip 安装(最常用,跨平台)
pip install pre-commit

# pipx 安装(隔离环境,推荐)
pipx install pre-commit

# macOS 也可用 Homebrew
brew install pre-commit

# uv 安装
uv tool install pre-commit

步骤 3:初始化 Git 钩子

cd your-project

# 安装 Git 钩子并下载 hook 依赖(首次执行较慢)
pre-commit install --install-hooks

# 验证安装
pre-commit --version

步骤 4:日常使用

# 提交代码(自动触发 pre-commit,仅检查暂存区变更文件)
git add .
git commit -m "Add new feature"

# 手动全量检查所有文件
pre-commit run --all-files

# 手动检查指定文件
pre-commit run --files ./src/demo.py ./src/utils.py

# 手动运行指定 hook
pre-commit run trailing-whitespace --all-files

# 更新所有 hook 到最新版本
pre-commit autoupdate

# 清理 hook 缓存环境(解决环境异常)
pre-commit clean

本地配置加速(国内网络)

pre-commit 默认从 GitHub 克隆 hook 仓库,国内网络可能较慢。有两种加速方案:

方案一:配置 GitCode 镜像仓库

将 repo 地址替换为 GitCode 镜像仓库。GitCode 提供了 GitHub 项目的镜像加速,路径规则为 https://gitcode.com/gh_mirrors/<前两字母>/<项目名>:

repos:
  # 使用 GitCode 镜像加速
  - repo: https://gitcode.com/gh_mirrors/pr/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-json
      - id: check-merge-conflict
      - id: check-added-large-files
      - id: detect-private-key

  - repo: https://gitcode.com/gh_mirrors/ru/ruff-pre-commit
    rev: v0.15.17
    hooks:
      - id: ruff-check
        args: [--fix]
      - id: ruff-format

  - repo: https://gitcode.com/GitHub_Trending/gi/gitleaks
    rev: v8.21.2
    hooks:
      - id: gitleaks

适用前提:镜像仓库仅加速 hook 仓库本身的克隆。如果 hook 运行时还需下载其他依赖(如 Go 环境、Node.js 包),仍需配置外网代理或使用国内源。

方案二:配置外网访问代理

# 设置 Git 代理(适用于所有 Git 操作,包括 pre-commit 克隆)
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

# 设置 pip 国内源加速(pre-commit 本身通过 pip 安装)
pip config set global.index-url https://repo.huaweicloud.com/repository/pypi/simple

PR 门禁检查

核心流程说明

PR 门禁与本地检查复用同一个 .pre-commit-config.yaml,无需重复配置。CI 中的核心策略是只检查 PR 变更文件(增量检查),既提升 CI 效率,又聚焦 PR 改动点:

  1. 获取 PR 增量文件列表:通过 Git 命令提取本次 PR 相对于目标分支的变更文件
  2. 过滤有效文件:排除删除/重命名文件,只保留新增和修改的文件
  3. 让 pre-commit 仅扫描增量文件:通过 pre-commit run --files <文件列表> 触发检查
  4. CI 门禁逻辑:检查失败则阻断 PR 合并,成功则放行

在 GitCode PR 中执行 pre-commit 检查

GitCode 平台提供三种在 PR 上执行 pre-commit 检查的方案,按优先级排列:

1. GitCode Action

GitCode Action 是 GitCode 平台原生的 CI/CD 自动化执行系统,可在仓库中定义工作流,由 PR、推送等仓库事件自动触发。pre-commit 专用 action pre-commit-action 已在平台试点上线,可在流水线中直接引用,无需自行编写检查脚本。

pre-commit-action(试点上线)

pre-commit-action 是 GitCode 平台提供的 pre-commit 专用 CI action,会自动安装 pre-commit 并执行钩子检查。默认按事件类型自动切换检查范围:PR 事件仅检查变更文件(增量),非 PR 事件检查全量文件。

输入/输出参数:action 的输入参数、输出参数以插件自身 WIKI 说明为准,本文档不展开。

使用前提

使用该 action 之前,请确认以下三项均已就绪:

  1. 代码仓已开启 Action:进入 项目设置 → 通用设置,勾选"启用 Actions"
  2. 代码仓已启用 PR 预合并:进入 项目设置 → 仓库设置,勾选"合并请求 PR 预合并"
  3. 项目根目录存在 .pre-commit-config.yaml:action 依赖该文件声明 hook 列表

如需了解更多告警屏蔽、pre-commit 配置等信息,请查阅:pre-commit 解决方案

执行机选择

.pre-commit-config.yaml 中 hooks 仓库地址决定执行机选择:

  • 使用外网执行机(推荐):当 hooks 来自 GitHub 等外部仓库(默认情况)时,需要使用部署在境外(香港、新加坡等)的外网执行机。境外机器可顺利访问 GitHub、PyPI 等外部网络
  • 使用 GitCode 默认执行机:当所有 hooks 均来自 GitCode 镜像仓(https://gitcode.com/ 开头)时,可使用 GitCode 默认执行机

判断依据:hooks 的 repo 地址以 https://gitcode.com/ 开头的是 GitCode 镜像仓,GitCode 默认执行机可直接访问;以 https://github.com/ 或其他外部地址开头的,需使用外网执行机。

配置示例

以下两个场景覆盖最常见的使用情况,每个场景先给出 .pre-commit-config.yaml,再给出对应的 action 流水线文件 pre-commit.yml。

场景一:hooks 来自 GitHub 等外部仓库(使用外网执行机)

步骤 1:在项目根目录创建 .pre-commit-config.yaml

# .pre-commit-config.yaml
minimum_pre_commit_version: "4.0"

repos:
  # GitHub 仓库 — pre-commit 官方基础检查工具
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-json
      - id: check-added-large-files
      - id: detect-private-key

  # GitHub 仓库 — Python 代码检查与格式化
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.15.17
    hooks:
      - id: ruff-check
        args: [--fix]
      - id: ruff-format

  # GitHub 仓库 — 敏感信息扫描
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.21.2
    hooks:
      - id: gitleaks

步骤 2:在 .gitcode/workflows/ 下创建 pre-commit.yml

name: pre-commit

on:
  pull_request_target: # 使用 pull_request_target 配合预合并,读取 PR 与目标分支合并后的最终代码
    branches:
      - "*"

jobs:
  pre-commit:
    name: pre-commit
    runs-on: ["self-hosted", "os=ubuntu", "arch=x64", "region=hk"] # 外网执行机:必须包含 'self-hosted',其他标签与执行机注册时保持一致
    steps:
      - name: checkout
        uses: checkout
        with:
          ref: ${{ atomgit.event.pull_request.merge_commit_sha || atomgit.event.pull_request.head.sha }} # 配合 PR 预合并,使用预合并 commit SHA 检出

      - name: setup-python
        uses: setup-python
        with:
          python-version: "3.12"

      - name: run pre-commit
        uses: openlibing/pre-commit-action@v1.0.0
        with:
          extra_args: ${{ inputs.extra_args }}
场景二:hooks 全部来自 GitCode 镜像仓(使用 GitCode 默认执行机)

步骤 1:在项目根目录创建 .pre-commit-config.yaml

# .pre-commit-config.yaml
minimum_pre_commit_version: "4.0"

repos:
  # GitCode 镜像仓 — pre-commit 官方基础检查工具
  - repo: https://gitcode.com/gh_mirrors/pr/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-json
      - id: check-added-large-files
      - id: detect-private-key

  # GitCode 镜像仓 — Python 代码检查与格式化
  - repo: https://gitcode.com/gh_mirrors/ru/ruff-pre-commit
    rev: v0.15.17
    hooks:
      - id: ruff-check
        args: [--fix]
      - id: ruff-format

  # GitCode 镜像仓 — 敏感信息扫描
  - repo: https://gitcode.com/GitHub_Trending/gi/gitleaks
    rev: v8.21.2
    hooks:
      - id: gitleaks

步骤 2:在 .gitcode/workflows/ 下创建 pre-commit.yml

name: pre-commit

on:
  pull_request_target:
    branches:
      - "*"

jobs:
  pre-commit:
    name: pre-commit
    runs-on: ["codearts-hosted", "ubuntu-latest", x64, "large"] # GitCode 默认执行机
    steps:
      - name: checkout
        uses: checkout
        with:
          ref: ${{ atomgit.event.pull_request.merge_commit_sha || atomgit.event.pull_request.head.sha }} # 配合 PR 预合并,使用预合并 commit SHA 检出

      - name: setup-python
        uses: setup-python
        with:
          python-version: "3.12"

      - name: run pre-commit
        uses: openlibing/pre-commit-action@v1.0.0
        with:
          extra_args: ${{ inputs.extra_args }}

外网执行机准备工作

使用外网执行机前,需要在组织或仓库层级完成 self-hosted runner 部署。可根据使用范围选择:

  • 组织级 Runner:由组织管理员统一管理,可在组织下所有仓库的流水线中共享使用。使用前需先创建 Runner 分组,再在分组下新增自定义 Runner
  • 仓库级 Runner:归属单个仓库,仅限本仓库流水线使用,可直接新增自定义 Runner

部署流程:进入 组织设置(或 仓库设置)→ 组织 Runner(或 仓库 Runner)→ 点击 新增自定义 Runner 按钮,按指引完成代理程序安装和标签配置。

上述"组织/仓库 Runner"菜单入口对应平台 actions 的 Runner 管理页面(Settings → Actions → Runners)。

新增自定义 Runner 步骤

  1. 选择部署地域:根据团队访问 GitHub、PyPI 等外部网络的需要,选择香港、新加坡等境外地域部署执行机
  2. 安装执行机代理:在目标机器上下载并安装 self-hosted runner 代理程序
  3. 配置标签:注册执行机时设置地域和系统相关标签(如 region=hk、os=ubuntu、arch=x64),流水线通过 runs-on: ['self-hosted', 标签] 精确调度

上线前的过渡方案

专用 action 上线前,可通过 GitCode 平台流水线配置自定义执行步骤,调用 通用 CI 脚本 完成 pre-commit 增量检查:在流水线中添加一个 Shell 类型步骤,设置环境变量 TARGET_BRANCH 为 PR 目标分支,执行 ./scripts/ci-pre-commit-pr.sh。

2. 第三方平台流水线(CodeArts Pipeline)

对于已使用华为云 CodeArts Pipeline 作为 CI/CD 平台的团队,可将 GitCode 仓库接入 CodeArts 流水线,通过 通用 CI 脚本 执行 pre-commit 增量检查。

接入步骤:

  1. 创建流水线:在 CodeArts 中创建流水线,代码源选择 GitCode 仓库,配置目标分支
  2. 添加构建任务:在流水线中添加构建步骤,基础镜像选择 python:3.12-slim(需包含 git)
  3. 执行通用脚本:在构建步骤中安装 pre-commit 并调用通用 CI 脚本:
# 安装依赖
pip install pre-commit
apt-get update && apt-get install -y git

# 配置 PR 目标分支(根据 CodeArts 流水线变量传入)
export TARGET_BRANCH=${TARGET_BRANCH:-main}

# 执行增量检查
chmod +x scripts/ci-pre-commit-pr.sh
./scripts/ci-pre-commit-pr.sh
  1. 配置门禁:在 CodeArts 流水线设置中,将该构建任务标记为必过检查,PR 合并前必须通过

适用场景:团队已有华为云 CodeArts 基础设施,或需要将 pre-commit 检查纳入更完整的 DevOps 流水线(构建、测试、部署一体化)。

3. Jenkins

对于已使用 Jenkins 作为 CI/CD 平台的团队,可将 GitCode 仓库接入 Jenkins 流水线,通过 通用 CI 脚本 执行 pre-commit 增量检查。

在 Jenkinsfile 中配置:

pipeline {
    agent any
    stages {
        stage('Pre-Commit Check') {
            when {
                expression { env.CHANGE_TARGET != null }  // 仅 PR 触发
            }
            steps {
                sh 'git fetch origin $CHANGE_TARGET --depth=1000'
                sh 'export TARGET_BRANCH=$CHANGE_TARGET && ./scripts/ci-pre-commit-pr.sh'
            }
        }
    }
}

适用场景:团队已有 Jenkins 基础设施,或需要将 pre-commit 检查纳入已有的 Jenkins 多阶段流水线。

在 GitHub PR 中执行 pre-commit 检查

GitHub 平台提供两种在 PR 上执行 pre-commit 检查的方案,按推荐度排列:

1. 使用 pre-commit.ci

pre-commit.ci 是 pre-commit 官方提供的托管 CI 服务,也是官方推荐的 PR 门禁方案。安装 GitHub App 后零配置即可在 PR 上运行与本地相同的 hook,无需编写 workflow 文件或检查脚本。

  • 零配置:安装 GitHub App 授权仓库后自动生效,无需在仓库中添加 workflow 文件
  • 自动修复:当格式化类 hook 修改文件时,自动将修复 commit 回推到 PR(可关闭)
  • 版本自更新:可定期自动更新 hook 的 rev 版本

pre-commit.ci 同时承担 PR 门禁和自动修复两个角色,完整配置方法见 在 PR 中使用 pre-commit 自动修复代码。

2. 使用 pre-commit action

pre-commit/action 是 pre-commit 官方提供的 GitHub Action,可在自建 GitHub Actions workflow 中运行 pre-commit。该 action 当前处于维护模式(不再新增功能),官方推荐优先使用 pre-commit.ci。

在 .github/workflows/pre-commit.yml 中配置:

name: pre-commit
on:
  pull_request:
    branches: [main, master, dev]

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

该 action 默认对全量文件运行所有 hook。如需指定单个 hook 或传入额外参数,通过 extra_args 配置:

- uses: pre-commit/action@v3.0.1
  with:
    extra_args: ruff-check --all-files

说明:pre-commit/action 不内置自动修复回推 PR 的功能(该功能在 v3.0.0 已移除)。如需自动修复,请使用 pre-commit.ci,或配合 git-auto-commit-action 等第三方 action。

PR 门禁拦截机制

CI 检查失败后,各平台的拦截方式:

平台 拦截方式 配置入口
GitHub Branch Protection Rules → Require status checks 仓库 Settings → Branches
GitCode 分支保护规则 → 必须通过 CI 检查 仓库设置 → 分支保护
GitLab Protected Branches → Require CI pass 仓库 Settings → Repository → Protected branches

关键原则:门禁拦截的是"新增问题"。对于存量项目的历史问题,应通过基线化管理逐步消化,而非一次性阻断所有 PR。详见 企业级治理指南。

通用 CI 脚本

通用 CI 脚本已存放于 scripts/ci-pre-commit-pr.sh,供 GitCode Action、CodeArts Pipeline、Jenkins 等 CI 平台引用。

脚本核心逻辑:

  1. 配置文件校验:未找到 .pre-commit-config.yaml 时直接放行
  2. 获取增量文件:通过 git diff --name-only --diff-filter=ACMR 提取 PR 相对目标分支的新增、修改、重命名文件(排除删除)
  3. 执行 pre-commit:通过 pre-commit run --files <文件列表> 仅检查增量文件
  4. 返回检查结果:检查失败时输出本地修复指引,并以非零退出码标识失败

依赖环境变量:

变量 说明 是否必填
TARGET_BRANCH PR 目标分支(如 main) 是
GIT_TOKEN 私仓访问凭据 否(公仓不需要)

使用前添加执行权限:

chmod +x scripts/ci-pre-commit-pr.sh

告警处理与屏蔽

pre-commit 的告警处理分为三个层面:调度层筛选(控制哪些文件传给 hook)、工具层抑制(控制具体工具的规则输出)和代码层屏蔽(在源码中标记豁免)。

层面一:调度层屏蔽(pre-commit 配置)

调度层屏蔽控制 pre-commit 把哪些文件传给 hook,适合排除生成代码、第三方依赖、锁文件等。

顶层配置(全局生效)

# .pre-commit-config.yaml 顶层配置
# 全局文件排除:对所有 hook 生效
exclude: |
  (?x)^(
    generated/.*|
    vendor/.*|
    third_party/.*|
    dist/.*|
    .*\.min\.js|
    package-lock\.json|
    go\.sum
  )$

# 全局文件包含:只检查匹配的文件
files: ^(src/|tests/)

# 首个 hook 失败后立即停止
fail_fast: false

# 默认运行阶段
default_stages: [pre-commit]

# 默认语言版本
default_language_version:
  python: python3.12

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: check-yaml

官方文档:顶层 exclude、顶层 files

Hook 级配置(单个 hook 生效)

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: check-yaml
        files: ^(\.github/|config/) # 只检查指定目录
        exclude: ^\.github/generated/ # 排除生成文件
      - id: trailing-whitespace
        exclude: \.(patch|diff|lock)$ # 排除补丁和锁文件
        types: [text] # 只检查文本文件
      - id: check-added-large-files
        args: [--maxkb=1024] # 修改大文件阈值为 1MB

官方文档:hook 级 files、hook 级 exclude、hook 级 types

层面二:工具层屏蔽(工具配置文件)

pre-commit 调度的具体工具有各自的配置文件来控制规则和排除。以下列出全部工具的配置文件屏蔽方式:

C/C++

工具 配置文件屏蔽方式 详细文档
ClangFormat .clang-format-ignore 文件 / DisableFormat、OneLineFormatOffRegex 配置 ClangFormat 告警抑制
Clang-Tidy .clang-tidy 中 Checks 筛选 / HeaderFilterRegex 排除头文件 Clang-Tidy 告警抑制
Cppcheck --suppress 参数 / .cppcheck-suppress 文件 / .cppcheck.cfg 配置 Cppcheck 告警抑制

Python

工具 配置文件屏蔽方式 详细文档
Ruff ruff.toml / pyproject.toml 中 exclude、ignore、per-file-ignores Ruff 告警抑制
Pylint pyproject.toml 中 messages_control.disable / --disable 参数 Pylint 告警抑制
Mypy pyproject.toml 中 overrides.ignore_errors / --ignore 参数 Mypy 告警抑制
Bandit skips / exclude_dirs 配置 / 命令行 -s 参数 Bandit 告警抑制

Java

工具 配置文件屏蔽方式 详细文档
Checkstyle SuppressionFilter XML / SuppressionSingleFilter Checkstyle 告警抑制
SpotBugs @SuppressFBWarnings 注解 / Filter XML SpotBugs 告警抑制
PMD @SuppressWarnings("PMD") / violationSuppressRegex 配置 PMD 告警抑制
Spotless Gradle targetExclude / Maven excludes Spotless 告警抑制
google-java-format Spotless toggleOffOn / exclude 目录 google-java-format 告警抑制
ErrorProne -Xep 命令行参数 / 配置文件 ErrorProne 告警抑制

Scala

工具 配置文件屏蔽方式 详细文档
Scalafmt project.excludeFilters / fileOverride Scalafmt 告警抑制
Scalafix .scalafix.conf 中 rules 移除 / 规则参数 Scalafix 告警抑制

JavaScript/TypeScript

工具 配置文件屏蔽方式 详细文档
ESLint eslint.config.js 中 ignores、rules ESLint 告警抑制
typescript-eslint eslint.config.js 中 rules typescript-eslint 告警抑制
Prettier .prettierignore / --ignore-path 参数 Prettier 告警抑制

Go

工具 配置文件屏蔽方式 详细文档
golangci-lint .golangci.yml 中 linters.exclusions golangci-lint 告警抑制
gosec 配置文件 exclude / exclude-rules gosec 告警抑制

Rust

工具 配置文件屏蔽方式 详细文档
rustfmt rustfmt.toml 中 ignore rustfmt 告警抑制
Clippy clippy.toml / 命令行 -A/-W/-D 参数 Clippy 告警抑制

Shell

工具 配置文件屏蔽方式 详细文档
ShellCheck .shellcheckrc / --exclude 参数 ShellCheck 告警抑制
shfmt EditorConfig ignore / pre-commit exclude shfmt 告警抑制

Lua

工具 配置文件屏蔽方式 详细文档
Luacheck .luacheckrc 中 ignore / exclude_files Luacheck 告警抑制
StyLua .styluaignore / --glob 参数 StyLua 告警抑制

Markdown

工具 配置文件屏蔽方式 详细文档
markdownlint 配置文件 rules: false / ignores markdownlint 告警抑制

通用 / 安全 / 拼写

工具 配置文件屏蔽方式 详细文档
Gitleaks .gitleaksignore / allowlists 配置 Gitleaks 告警抑制
detect-secrets 基线文件 / --exclude-files 参数 detect-secrets 告警抑制
Codespell 配置文件 skip / ignore-words-list Codespell 告警抑制
Typos _typos.toml 中 extend-exclude / extend-words Typos 告警抑制
CodeQL codeql-config.yml 中 paths-ignore / query-filters CodeQL 告警抑制
Xmllint 命令行参数 / pre-commit exclude Xmllint 告警抑制

层面三:代码层屏蔽(源码注释与属性)

代码级屏蔽由具体工具提供,在源码中标记豁免特定行、块或文件。以下列出全部支持代码级屏蔽的工具:

C/C++

工具 行级 块级 文件级 文档
ClangFormat -- // clang-format off / // clang-format on .clang-format-ignore ClangFormat 屏蔽
Clang-Tidy // NOLINT(check) / // NOLINTNEXTLINE(check) // NOLINTBEGIN ... // NOLINTEND -- Clang-Tidy 屏蔽
Cppcheck // cppcheck-suppress [symbolName=] -- -- Cppcheck 屏蔽

Python

工具 行级 块级 文件级 文档
Ruff # noqa: RULE # ruff: disable[RULE] / # ruff: enable[RULE] # ruff: noqa Ruff noqa
Pylint # pylint: disable=RULE # pylint: disable / # pylint: enable # pylint: disable=RULE(文件顶部) Pylint 屏蔽
Mypy # type: ignore[error-code] -- # mypy: ignore-errors / # mypy: disable-error-code Mypy 屏蔽
Bandit # nosec -- -- Bandit 屏蔽

Java

工具 行级 块级 文件级 文档
Spotless -- // spotless:off / // spotless:on -- Spotless 屏蔽
google-java-format -- // @formatter:off / // @formatter:on -- google-java-format 屏蔽
Checkstyle CHECKSTYLE OFF: <rule> / @SuppressWarnings CHECKSTYLE:OFF / CHECKSTYLE:ON -- Checkstyle 屏蔽
PMD // NOPMD / @SuppressWarnings("PMD.xxx") -- -- PMD 屏蔽
ErrorProne @SuppressWarnings -- -- ErrorProne 屏蔽
SpotBugs @SuppressFBWarnings -- -- SpotBugs 屏蔽

Scala

工具 行级 块级 文件级 文档
Scalafix // scalafix:ok // scalafix:off / // scalafix:on -- Scalafix 屏蔽

JavaScript/TypeScript

工具 行级 块级 文件级 文档
Prettier // prettier-ignore <!-- prettier-ignore-start --> / <!-- prettier-ignore-end --> -- Prettier 屏蔽
ESLint // eslint-disable-line / // eslint-disable-next-line /* eslint-disable */ / /* eslint-enable */ /* eslint-disable */(文件顶部) ESLint 规则
typescript-eslint // eslint-disable-next-line @ts-... /* eslint-disable @ts-... */ /* eslint-disable */(文件顶部) typescript-eslint 屏蔽

Go

工具 行级 块级 文件级 文档
golangci-lint //nolint:linter //nolint:linter(函数级) //nolint:linter(文件顶部) golangci-lint 屏蔽
gosec // #nosec G101 / //gosec:disable -- -- gosec 屏蔽

Rust

工具 行级 块级 文件级 文档
Clippy #[allow(clippy::rule)] #![allow(clippy::rule)](crate 级) -- Clippy 屏蔽
rustfmt #[rustfmt::skip] -- -- rustfmt 屏蔽

Shell

工具 行级 块级 文件级 文档
ShellCheck # shellcheck disable=SCxxxx # shellcheck disable / # shellcheck enable # shellcheck disable(shebang 后) ShellCheck 忽略

Lua

工具 行级 块级 文件级 文档
StyLua -- stylua: ignore -- stylua: ignore-start / -- stylua: ignore-end -- StyLua 屏蔽
Luacheck -- luacheck: ignore -- luacheck: push / -- luacheck: pop -- luacheck: ignore(文件顶部) Luacheck 屏蔽

Markdown

工具 行级 块级 文件级 文档
markdownlint <!-- markdownlint-disable-line --> / <!-- markdownlint-disable-next-line --> <!-- markdownlint-disable --> / <!-- markdownlint-enable --> <!-- markdownlint-disable-file --> markdownlint 屏蔽

通用 / 安全 / 拼写

工具 行级 块级 文件级 文档
Gitleaks //gitleaks:allow / #gitleaks:allow -- -- Gitleaks 屏蔽
detect-secrets # pragma: allowlist secret / // pragma: allowlist nextline secret -- -- detect-secrets 屏蔽
Codespell # codespell:ignore word -- -- Codespell 屏蔽
Typos -- # spellchecker:off / # spellchecker:on -- Typos 屏蔽

不支持代码级屏蔽的工具:Scalafmt、shfmt、CodeQL、Xmllint、pre-commit。这些工具仅支持配置文件或命令行参数屏蔽,参见上方工具层屏蔽表格。

屏蔽粒度选择原则

遵循最小影响范围原则:

代码层屏蔽(首选)→ 工具层屏蔽(次选)→ 调度层屏蔽(谨慎)
  • 代码层屏蔽最精确,只影响特定行,风险最低
  • 工具层屏蔽影响工具的规则配置,可能掩盖后续新增的真实问题
  • 调度层屏蔽影响文件范围,可能跳过整个文件的检查

详见 企业级治理指南:误报审批与例外治理。


在 PR 中使用 pre-commit 自动修复代码

针对存量项目中存在大量风格类历史问题、开发者仅修改少量代码却被 PR 门禁拦截的场景,pre-commit 的自动修复能力可在 PR 上自动修复代码风格问题并回推提交,开发者无需手动处理格式问题,显著提升开发体验。

在 GitCode PR 中启用 pre-commit 代码自动修复

openLiBing 平台基于 .pre-commit-config.yaml 提供代码风格自动修复服务,覆盖以下 pre-commit 可集成的风格类格式化工具(社区成熟、误报率极低),后续会根据社区需求持续补充:

  • trailing-whitespace — 全语言,移除行尾空白字符
  • end-of-file-fixer — 全语言,确保文件以换行符结尾
  • clang-format — C/C++ 代码格式化
  • ruff-format — Python 代码格式化

启用条件

开启自动修复需同时满足以下三个条件:

  1. 代码仓配置:代码仓根目录已配置 .pre-commit-config.yaml
  2. 打开自动修复开关:在 openLiBing 流水线或代码仓配置中打开"代码风格自动修复"功能开关

优先使用流水线配置,若未使用CodeArts Pipeline,则可在代码仓中配置(缺点,不支持在PR流水线报告中呈现自动修复结果,仅commit记录体现)

  1. (仅 fork 开发模式)添加机器人账号:开发者在个人 fork 仓库添加对应社区机器人账号作为自动修复代码提交人;未添加的开发者,PR 不会进行自动修复,但不影响流水线执行和代码合入

fork 开发模式说明:由于 GitCode 暂无 App 代码仓授权提交模式,目前通过添加社区机器人账号作为代码提交人。各社区需添加自己的 robot 账号(已在 openLiBing 平台项目配置过 GitCode token,且令牌需要有用户读写权限),并赋予 robot 开发者及以上权限(可提交代码)。个人 fork 仓库添加成员需邀请并得到对方同意,目前已支持开发者邀请后自动同意(1-2 分钟延迟)。

已开通邀请自动同意的社区及机器人:

社区 机器人账号
openLiBing 社区 openLiBingCI
Ascend 社区 ascend-robot
Kunpeng 社区 kunpeng-bot

应用效果

配置完成后,修改一个存量文件(存在代码风格问题)并提交 PR,将产生以下效果:

  1. 流水线报告体现自动修复信息:流水线默认在自动修复完成后执行,避免检测代码不一致
  2. 自动提交修复 commit:自动修复的代码会自动提交一条 commit 记录,提交信息为 [openlibing.ci] auto fixes by pre-commit
  3. 自动提交检视意见:系统基于自动修复的代码给 PR 创建者提交一条检视意见(每个文件提一条),开发者需确认无问题后将检视意见"未解决"修改为"已解决"

在 GitHub PR 中启用 pre-commit 代码自动修复

pre-commit.ci 是 pre-commit 框架官方提供的托管 CI 服务,支持在 GitHub PR 上运行与本地相同的 hook;此外对文件产生自动修改(如clang-format,ruff-format)时,还可配置自动将修复 commit 回推到 PR。

适用前提

  • 仓库托管在 GitHub(pre-commit.ci 目前仅支持 GitHub),且已安装Github APP:pre-commit.ci
  • 仓库根目录已有 .pre-commit-config.yaml

配置方法

在 .pre-commit-config.yaml 顶层添加 ci: 段:

# auto fix pr from https://pre-commit.ci
ci:
  autofix_prs: true # true:自动修复回推PR; false:PR仅检查不提交;可在PR下评论或打上标签pre-commit.ci autofix,手动触发自动修复
  autoupdate_schedule: weekly # 按周期自动更新钩子版本;可选:'weekly'(默认), 'monthly', 'quarterly'

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.15.17
    hooks:
      - id: ruff-format # 格式化类 hook,适合自动修复
      - id: ruff-check
        args: []
# --fix # 如果希望在PR自动修复,可启用--fix参数

启用步骤

  1. 编写配置:在 .pre-commit-config.yaml 中添加 ci: 段,确认 autofix_prs: true
  2. 安装 GitHub App:前往 pre-commit.ci 官方安装页,授权目标仓库或组织。开源仓库免费,私有仓库通过 GitHub Marketplace 付费
  3. 验证闭环:创建测试 PR,故意引入格式错误,观察 pre-commit.ci 是否自动产生修复 commit

业界社区实例


常见问题与排查

提交代码时 pre-commit 未拦截

原因:本地未安装 pre-commit 或未执行初始化。

解决方案:

# 确认已安装 pre-commit
pip install pre-commit

# 在项目根目录初始化 Git 钩子
pre-commit install --install-hooks

hook 仓库访问慢或无法访问

原因:pre-commit 默认从 GitHub 克隆 hook 仓库,国内网络可能受限。

方案一(推荐):配置外网访问代理。

方案二:使用 GitCode 镜像仓库。将 repo 地址替换为 GitCode 镜像,详见 本地配置加速。

注意:镜像仓库仅加速 hook 仓库本身的克隆。如果 hook 运行时还需下载其他依赖(如 Go 环境、Node.js 包),仍需配置外网代理或使用国内源。

报错:Expected one of commit, commit-msg

pre_commit.clientlib.InvalidManifestError:
==> At key: stages
=====> Expected one of commit, ... , push but got: 'pre-commit'

原因:pre-commit 新版本的 stages 枚举值变更,旧版本 Python 不兼容。

解决方案:升级 Python 版本至 3.10 及以上。

CI 中 pre-commit 检查了全量文件

原因:CI 脚本未使用 --files 参数指定增量文件,或未正确获取变更文件列表。

解决方案:使用 通用 CI 脚本,确保通过 git diff --name-only --diff-filter=ACMR 获取增量文件列表,并通过 pre-commit run --files 传入。

本地检查通过但 CI 失败

原因:本地和 CI 的 pre-commit 版本或 hook 版本不一致。

解决方案:

  1. 在 .pre-commit-config.yaml 中锁定 minimum_pre_commit_version
  2. CI 中安装与本地相同版本的 pre-commit
  3. 使用 pre-commit autoupdate --freeze 将 hook 版本锁定为 commit hash

格式化 hook 修改了文件但未暂存

原因:格式化 hook(如 trailing-whitespace、ruff-format)自动修改了文件内容,但修改未加入暂存区。

解决方案:

# 重新暂存格式化后的文件
git add .

# 再次提交
git commit -m "your message"

相关工具与语言指南

工具详解

工具 说明 文档
pre-commit 多语言 Git hooks 调度框架 工具详解
Ruff Python Linter 与格式化器 工具详解
ESLint JavaScript/TypeScript Linter 工具详解
typescript-eslint TypeScript 专用 ESLint 规则集 工具详解
Prettier 多语言代码格式化器 工具详解
Gitleaks Git 密钥泄露检测 工具详解
detect-secrets 密钥泄露检测(备选) 工具详解
Codespell 拼写错误检查 工具详解
Typos 拼写错误检查(备选) 工具详解
Mypy Python 类型检查 工具详解
Bandit Python 安全扫描 工具详解
Pylint Python 深度质量检查 工具详解
ShellCheck Shell 静态分析 工具详解
shfmt Shell 格式化 工具详解
ClangFormat C/C++ 格式化 工具详解
Clang-Tidy C/C++ 静态分析 工具详解
Cppcheck C/C++ 静态分析 工具详解
golangci-lint Go 聚合 Linter 工具详解
gosec Go 安全扫描 工具详解
rustfmt Rust 格式化 工具详解
Clippy Rust Lint 工具详解
Checkstyle Java 代码风格检查 工具详解
SpotBugs Java 字节码分析 工具详解
PMD Java 多语言静态分析 工具详解
Spotless Java 多语言格式化调度 工具详解
google-java-format Java 格式化 工具详解
ErrorProne Java 编译期 Bug 检测 工具详解
Scalafmt Scala 格式化 工具详解
Scalafix Scala 代码质量 工具详解
Luacheck Lua 静态分析 工具详解
StyLua Lua 格式化 工具详解
markdownlint Markdown 文档检查 工具详解
CodeQL 多语言语义安全分析 工具详解
Xmllint XML 格式验证 工具详解

语言工程落地指南

语言/场景 pre-commit 推荐组合 文档
Python Ruff + Mypy + Bandit + Gitleaks + Codespell Python 指南
JavaScript/TypeScript ESLint + Prettier + Gitleaks JS/TS 指南
Go golangci-lint + gosec + Gitleaks Go 指南
Java Checkstyle + SpotBugs + PMD + Spotless Java 指南
Scala Scalafmt + Scalafix Scala 指南
Rust rustfmt + Clippy Rust 指南
C/C++ ClangFormat + Clang-Tidy + Cppcheck C/C++ 指南
Shell ShellCheck + shfmt Shell 指南
Lua Luacheck + StyLua Lua 指南
Markdown markdownlint + Codespell Markdown 指南
YAML 通用基础 hook + Gitleaks YAML 指南
JSON 通用基础 hook JSON 指南
XML Xmllint + 通用基础 hook XML 指南
通用 pre-commit-hooks + Gitleaks + Codespell + Typos 通用指南

治理参考