本文档已迁移至 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 改动点:
- 获取 PR 增量文件列表:通过 Git 命令提取本次 PR 相对于目标分支的变更文件
- 过滤有效文件:排除删除/重命名文件,只保留新增和修改的文件
- 让 pre-commit 仅扫描增量文件:通过
pre-commit run --files <文件列表>触发检查 - 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 之前,请确认以下三项均已就绪:
- 代码仓已开启 Action:进入 项目设置 → 通用设置,勾选"启用 Actions"
- 代码仓已启用 PR 预合并:进入 项目设置 → 仓库设置,勾选"合并请求 PR 预合并"
- 项目根目录存在
.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 步骤
- 选择部署地域:根据团队访问 GitHub、PyPI 等外部网络的需要,选择香港、新加坡等境外地域部署执行机
- 安装执行机代理:在目标机器上下载并安装 self-hosted runner 代理程序
- 配置标签:注册执行机时设置地域和系统相关标签(如
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 增量检查。
接入步骤:
- 创建流水线:在 CodeArts 中创建流水线,代码源选择 GitCode 仓库,配置目标分支
- 添加构建任务:在流水线中添加构建步骤,基础镜像选择
python:3.12-slim(需包含 git) - 执行通用脚本:在构建步骤中安装 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
- 配置门禁:在 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 平台引用。
脚本核心逻辑:
- 配置文件校验:未找到
.pre-commit-config.yaml时直接放行 - 获取增量文件:通过
git diff --name-only --diff-filter=ACMR提取 PR 相对目标分支的新增、修改、重命名文件(排除删除) - 执行 pre-commit:通过
pre-commit run --files <文件列表>仅检查增量文件 - 返回检查结果:检查失败时输出本地修复指引,并以非零退出码标识失败
依赖环境变量:
| 变量 | 说明 | 是否必填 |
|---|---|---|
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)] |
# |
-- | 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 代码格式化
启用条件
开启自动修复需同时满足以下三个条件:
- 代码仓配置:代码仓根目录已配置
.pre-commit-config.yaml - 打开自动修复开关:在 openLiBing 流水线或代码仓配置中打开"代码风格自动修复"功能开关
优先使用流水线配置,若未使用CodeArts Pipeline,则可在代码仓中配置(缺点,不支持在PR流水线报告中呈现自动修复结果,仅commit记录体现)
- (仅 fork 开发模式)添加机器人账号:开发者在个人 fork 仓库添加对应社区机器人账号作为自动修复代码提交人;未添加的开发者,PR 不会进行自动修复,但不影响流水线执行和代码合入
fork 开发模式说明:由于 GitCode 暂无 App 代码仓授权提交模式,目前通过添加社区机器人账号作为代码提交人。各社区需添加自己的 robot 账号(已在 openLiBing 平台项目配置过 GitCode token,且令牌需要有用户读写权限),并赋予 robot 开发者及以上权限(可提交代码)。个人 fork 仓库添加成员需邀请并得到对方同意,目前已支持开发者邀请后自动同意(1-2 分钟延迟)。
已开通邀请自动同意的社区及机器人:
| 社区 | 机器人账号 |
|---|---|
| openLiBing 社区 | openLiBingCI |
| Ascend 社区 | ascend-robot |
| Kunpeng 社区 | kunpeng-bot |
应用效果
配置完成后,修改一个存量文件(存在代码风格问题)并提交 PR,将产生以下效果:
- 流水线报告体现自动修复信息:流水线默认在自动修复完成后执行,避免检测代码不一致
- 自动提交修复 commit:自动修复的代码会自动提交一条 commit 记录,提交信息为
[openlibing.ci] auto fixes by pre-commit - 自动提交检视意见:系统基于自动修复的代码给 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参数
启用步骤
- 编写配置:在
.pre-commit-config.yaml中添加ci:段,确认autofix_prs: true - 安装 GitHub App:前往 pre-commit.ci 官方安装页,授权目标仓库或组织。开源仓库免费,私有仓库通过 GitHub Marketplace 付费
- 验证闭环:创建测试 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 版本不一致。
解决方案:
- 在
.pre-commit-config.yaml中锁定minimum_pre_commit_version - CI 中安装与本地相同版本的 pre-commit
- 使用
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 | 通用指南 |
治理参考
- 企业级代码检查治理指南 — 存量项目引入策略、规则灰度发布、误报审批流程、多仓库模板分发
- pre-commit 工具详解 — 安装方式、配置字段、命令行接口、官方文档链接