- Git
pre-commit設定|.pre-commit-config.yamlとフック一覧
pre-commit は、Git のコミット前などに動かすチェック(フック)を .pre-commit-config.yaml にまとめ、言語ごとの実行環境まで自動で用意する道具です。 フックは GitHub などのリポジトリから取得され、版(rev)で固定されます。チーム全員と CI で同じチェックを同じ版で動かせます。
pip install pre-commit # または pipx install pre-commit / brew install pre-commit
pre-commit sample-config > .pre-commit-config.yaml
pre-commit autoupdate # rev を最新のタグに更新
pre-commit install # .git/hooks/pre-commit を作る
pre-commit run --all-files # 全ファイルに一度かける
| 手元で確かめたこと | 結果 |
|---|---|
sample-config の rev |
v3.2.0。autoupdate で v6.0.0 に更新された |
| 初回のコミット | フックの環境づくりを含めて 6.6秒。4つのうち3つが Failed(自動修正2・YAML の誤り1) |
| 9リポジトリ分の環境 | キャッシュは合計 約250MB(mypy と型の追加パッケージだけで 83MB) |
2回目以降の run --all-files |
18フックで 3.2〜5.0秒(小さなリポジトリ) |
autoupdate で gitleaks |
v8.30.1 → v8.30.0 に下がった(既定ブランチから辿れる最新タグを使うため) |
gitleaks-system フック |
そのままでは accepts at most 1 arg(s), received 4 で失敗。pass_filenames: false で動いた |
CI で run --all-files |
gitleaks のフックはコミット済みの秘密情報を見つけない(--staged で調べるため) |
確認環境:pre-commit 4.7.0(PyPI、Python 3.11.15)を Ubuntu 24.04 で動かし、フックは GitHub から取得しました(pre-commit-hooks v6.0.0、ruff-pre-commit v0.17.0、mirrors-prettier v3.9.10、shellcheck-py v0.11.0.1、check-jsonschema 0.38.2、gitleaks v8.30.1、conventional-pre-commit v4.4.0、mirrors-mypy v2.4.0)。CI のワークフローは actionlint 1.7.12 で検査しました。設定キーと stages は pre-commit の公式サイトとソースで確かめています(確認日 2026年10月13日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「pre-commit設定|.pre-commit-config.yamlとフック一覧」
しくみ:何がどこで動くか
flowchart LR
C["git commit"] --> H[".git/hooks/pre-commit<br/>(pre-commit install で作成)"]
H --> P["pre-commit<br/>.pre-commit-config.yaml を読む"]
P --> R["フックのリポジトリを取得<br/>~/.cache/pre-commit"]
R --> E["言語ごとの環境<br/>python venv / node / go ..."]
E --> F["ステージしたファイルだけに実行"]
F -->|"失敗・修正あり"| X["コミットを止める"]
F -->|"すべて成功"| OK["コミットされる"]
| 動き | 内容 |
|---|---|
| 対象のファイル | git commit ではステージしたファイルだけ。run --all-files で全ファイル |
| ステージしていない変更 | 一時的に退避してから実行する([WARNING] Unstaged files detected. と表示) |
| フックがファイルを直した | files were modified by this hook で Failed。直った内容を git add して、もう一度コミットする |
| 環境の場所 | ~/.cache/pre-commit(PRE_COMMIT_HOME か XDG_CACHE_HOME で変えられる) |
| 環境の作成 | フックごとに初回だけ。[INFO] Once installed this environment will be reused. |
pre-commit install で作られる .git/hooks/pre-commit は、作ったときの Python の場所を書き込んだ短いシェルスクリプトでした。仮想環境を消すと、pre-commit コマンドを探しに行き、見つからなければ `pre-commit` not found. Did you forget to activate your virtualenv? で止まります。
最初の設定と実行結果
sample-config が出す設定です。
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
pre-commit autoupdate
# [https://github.com/pre-commit/pre-commit-hooks] updating v3.2.0 -> v6.0.0
行末に空白がある Python ファイルと、閉じかっこが無い YAML をステージしてコミットした結果です。
[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
trim trailing whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook
Fixing src/app.py
fix end of files.........................................................Failed
- hook id: end-of-file-fixer
- exit code: 1
- files were modified by this hook
Fixing src/app.py
check yaml...............................................................Failed
- hook id: check-yaml
- exit code: 1
while parsing a flow sequence
in "broken.yaml", line 1, column 6
expected ',' or ']', but got '<stream end>'
in "broken.yaml", line 2, column 1
check for added large files..............................................Passed
自動で直すフックも、直したときは Failed になりコミットは止まります。 直った内容を確かめて git add し、もう一度コミットします。
コピペ用の .pre-commit-config.yaml
Python・JavaScript・シェル・GitHub Actions があるリポジトリ向けの設定です。pre-commit validate-config を通り、この設定で run --all-files を動かした結果を下に載せています(gitleaks だけは、後で説明する理由で gitleaks-system に替えて動かしました)。
# pre-commit 4.x 用
minimum_pre_commit_version: "3.2.0"
default_install_hook_types: [pre-commit, commit-msg]
default_stages: [pre-commit]
exclude: ^(vendor/|dist/|.*\.min\.js$)
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: end-of-file-fixer
- id: check-yaml
args: [--allow-multiple-documents]
- id: check-json
- id: check-toml
- id: check-added-large-files
args: [--maxkb=500]
- id: check-merge-conflict
- id: check-case-conflict
- id: mixed-line-ending
args: [--fix=lf]
- id: detect-private-key
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: no-commit-to-branch
args: [--branch, main]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.17.0
hooks:
- id: ruff-check
args: [--fix]
- id: ruff-format
- repo: https://github.com/rbubley/mirrors-prettier
rev: v3.9.10
hooks:
- id: prettier
types_or: [javascript, ts, tsx, css, json, markdown]
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.11.0.1
hooks:
- id: shellcheck
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.38.2
hooks:
- id: check-github-workflows
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.1
hooks:
- id: gitleaks
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v4.4.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
pre-commit install
# pre-commit installed at .git/hooks/pre-commit
# pre-commit installed at .git/hooks/commit-msg
default_install_hook_types に書いた種類だけ、pre-commit install で Git のフックが作られます。 commit-msg や pre-push のフックを使うときは、ここに足すか pre-commit install --hook-type pre-push を実行します。
わざと誤りを入れたファイルに pre-commit run --all-files をかけた結果です(抜粋)。
check yaml...............................................................Failed
check json...........................................(no files to check)Skipped
don't commit to branch...................................................Failed
- hook id: no-commit-to-branch
- exit code: 1
ruff check...............................................................Failed
- hook id: ruff-check
- files were modified by this hook
Found 2 errors (2 fixed, 0 remaining).
ruff format..............................................................Failed
- hook id: ruff-format
- files were modified by this hook
1 file reformatted
prettier.................................................................Failed
- hook id: prettier
- files were modified by this hook
web/main.js 75ms
shellcheck...............................................................Failed
- hook id: shellcheck
- exit code: 1
In run.sh line 2:
echo $1
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Validate GitHub Workflows................................................Passed
ruff は使っていない import os,sys を消して整形し、prettier は const x = {a:1,\n b:2} を const x = { a: 1, b: 2 }; にしました。直したあと、別のブランチで実行するとすべて Passed になりました。
コミットメッセージの形式(Conventional Commits)を確かめる commit-msg フックの結果です。
Conventional Commit......................................................Failed
- hook id: conventional-pre-commit
- exit code: 1
[Bad commit message] >> いろいろ修正
Your commit message does not follow Conventional Commits formatting
https://www.conventionalcommits.org/
chore: add pre-commit config ではコミットできました。メッセージの書き方は、関連記事「コミットメッセージの書き方|ルール・例文・プレフィックス一覧」で扱っています。
gitleaks のフックで気をつけること
id: gitleaks は language: golang なので、フックの環境づくりで Go のビルドが走ります。 手元の Go 1.24.7(GOTOOLCHAIN=local)では次のエラーで止まりました。
go: go.mod requires go >= 1.24.11 (running go 1.24.7; GOTOOLCHAIN=local)
gitleaks のリポジトリには3つのフックがあります。
| id | language | 必要なもの |
|---|---|---|
gitleaks |
golang | Go(go.mod が求める版以上) |
gitleaks-docker |
docker_image | Docker |
gitleaks-system |
system | PATH に gitleaks のバイナリ |
gitleaks-system は、そのままだと失敗しました。 gitleaks と違って pass_filenames: false が定義されておらず、ファイル名が引数に渡るためです。
Error: accepts at most 1 arg(s), received 4
Usage:
gitleaks git [flags] [repo]
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.1
hooks:
- id: gitleaks-system
pass_filenames: false
この設定で、ステージした config.env の AWS のアクセスキーを見つけました。
Finding: AWS_ACCESS_KEY_ID=REDACTED
Secret: REDACTED
RuleID: aws-access-token
File: config.env
Line: 1
WRN leaks found: 1
フックの gitleaks git --pre-commit --staged は、ステージした差分だけを調べます。 --no-verify でコミットされた秘密情報は、そのあと pre-commit run --all-files をかけても Passed でした。同じリポジトリで gitleaks git .(履歴を調べる)を動かすと leaks found: 1 になりました。CI では履歴を調べる別のステップを置きます。秘密情報の管理は、関連記事「.envの使い方と注意点|APIキーを安全に管理する方法」で扱っています。
設定ファイルの書き方
最上位のキー
| キー | 既定値 | 意味 |
|---|---|---|
repos |
(必須) | フックのリポジトリの一覧 |
default_install_hook_types |
[pre-commit] |
pre-commit install で作る Git フックの種類 |
default_stages |
すべて | stages を書いていないフックが動くステージ |
default_language_version |
{} |
言語ごとの既定の版(例:python: python3.13) |
files |
'' |
対象にするファイルの正規表現 |
exclude |
^$ |
外すファイルの正規表現 |
fail_fast |
false |
true で最初の失敗で止める |
minimum_pre_commit_version |
'0' |
必要な pre-commit の版 |
フックごとのキー
| キー | 例 | 意味 |
|---|---|---|
id |
ruff-check |
使うフック(必須) |
args |
[--fix] |
追加の引数 |
files / exclude |
^src/ |
正規表現で対象を絞る |
types / types_or / exclude_types |
[python] |
ファイルの種類で絞る(types は AND、types_or は OR) |
stages |
[pre-push] |
動くタイミング |
additional_dependencies |
[types-requests] |
フックの環境に足すパッケージ |
language_version |
python3.13 |
言語の版 |
always_run |
true |
対象のファイルが無くても動かす |
pass_filenames |
false |
ファイル名を引数に渡さない |
require_serial |
true |
並列に分けず1回で動かす |
verbose |
true |
成功しても出力を表示する |
alias / name |
- | 別名・表示名 |
files・exclude は正規表現です。 exclude: ^(vendor/|dist/) のように、パスの先頭からの一致で書きます。glob(*.min.js)ではないので、.*\.min\.js$ と書きます。
rev が無いと設定エラーになります。 pre-commit validate-config の出力です。
==> At Repository(repo='https://github.com/pre-commit/pre-commit-hooks')
=====> Missing required key: rev
自分で書くフック(repo: local)
- repo: local
hooks:
- id: no-print
name: print() を残さない
language: pygrep
entry: '^\s*print\('
types: [python]
exclude: ^scripts/
- id: unit-test
name: pytest(push 前だけ)
language: unsupported # pre-commit 4.4.0 より前は system
entry: pytest -q
pass_filenames: false
always_run: true
stages: [pre-push]
pygrep は正規表現に一致した行があると失敗するフックです。手元では src/app.py:5:print(add(1, 2)) で Failed になりました。
language: system と script は、pre-commit 4.4.0 から unsupported と unsupported_script に名前が変わりました。 公式サイトでは、以前の名前は将来なくなると案内されています。4.7.0 では system と書いても内部で unsupported に読み替えられ、動きました。language を打ち間違えると、使える値の一覧が出ます。
=====> Expected one of conda, coursier, dart, docker, docker_image, dotnet, fail, golang, haskell, julia, lua, node, perl, pygrep, python, r, ruby, rust, swift, unsupported, unsupported_script but got: 'systm'
よく使うフック一覧
pre-commit-hooks(v6.0.0)
| id | 何をするか | 自動修正 |
|---|---|---|
trailing-whitespace |
行末の空白を消す(--markdown-linebreak-ext=md で Markdown の改行を残す) |
する |
end-of-file-fixer |
ファイル末尾を改行1つにそろえる | する |
mixed-line-ending |
改行コードの混在を直す(--fix=lf) |
する |
check-yaml / check-json / check-toml / check-xml |
構文を確かめる | しない |
check-added-large-files |
大きいファイルの追加を止める(既定 500KB、--maxkb) |
しない |
check-merge-conflict |
<<<<<<< などの残りを見つける |
しない |
check-case-conflict |
大文字小文字だけ違う名前を見つける | しない |
detect-private-key |
秘密鍵の追加を止める | しない |
detect-aws-credentials |
AWS CLI の認証情報ファイルにあるキーを見つける | しない |
check-executables-have-shebangs |
実行権限があるのに #! が無いファイル |
しない |
check-shebang-scripts-are-executable |
#! があるのに実行権限が無いファイル |
しない |
no-commit-to-branch |
main などへの直接コミットを止める | しない |
debug-statements |
Python の breakpoint()・pdb の残り |
しない |
check-ast |
Python として読めるか | しない |
pretty-format-json |
JSON を整形(--autofix) |
引数による |
requirements-txt-fixer |
requirements.txt を並べ替える | する |
check-illegal-windows-names |
Windows で使えないファイル名 | しない |
ほかのリポジトリのフック
| リポジトリ(版) | id | 用途 | language |
|---|---|---|---|
| astral-sh/ruff-pre-commit(v0.17.0) | ruff-check・ruff-format |
Python のリントと整形 | python |
| rbubley/mirrors-prettier(v3.9.10) | prettier |
JS・TS・CSS・JSON・Markdown の整形 | node |
| pre-commit/mirrors-eslint(v10.12.0) | eslint |
JS・TS のリント | node |
| pre-commit/mirrors-mypy(v2.4.0) | mypy |
Python の型チェック | python |
| shellcheck-py/shellcheck-py(v0.11.0.1) | shellcheck |
シェルスクリプトの検査 | python |
| python-jsonschema/check-jsonschema(0.38.2) | check-github-workflows・check-github-actions・check-dependabot・check-renovate・check-compose-spec |
設定ファイルをスキーマで検査 | python |
| rhysd/actionlint(v1.7.12) | actionlint・actionlint-system |
GitHub Actions の検査 | golang / system |
| adrienverge/yamllint(v1.38.0) | yamllint |
YAML の書き方 | python |
| gitleaks/gitleaks(v8.30.1) | gitleaks・gitleaks-system |
秘密情報 | golang / system |
| codespell-project/codespell(v2.4.3) | codespell |
英単語の綴り | python |
| compilerla/conventional-pre-commit(v4.4.0) | conventional-pre-commit |
コミットメッセージ(commit-msg) | python |
| hadolint/hadolint(v2.15.1) | hadolint・hadolint-docker |
Dockerfile の検査 | system / docker_image |
| golangci/golangci-lint(v2.14.0) | golangci-lint・golangci-lint-fmt |
Go のリントと整形 | golang |
| antonbabenko/pre-commit-terraform(v1.109.2) | terraform_fmt・terraform_validate・terraform_tflint |
Terraform | script |
版はいずれも 2026年10月13日に git ls-remote で確かめた最新のタグです。language: system・script のフックは、ツール本体を自分で入れておく必要があります。 python・node のフックは pre-commit が環境を作るので、ツールを入れなくても動きます。
pre-commit/mirrors-prettier は 2024年4月のコミットで archived になっています(最後のタグは v4.0.0-alpha.8)。この記事では、prettier 3.x の版が続いている rbubley/mirrors-prettier を使いました。ESLint の設定は関連記事「ESLint flat config設定|v10対応の完成形コピペ集」で扱っています。
言語ごとの例
# Go
- repo: https://github.com/golangci/golangci-lint
rev: v2.14.0
hooks:
- id: golangci-lint # language: golang(Go のビルドが走る)
# Java / Kotlin(ビルドツールに任せる)
- repo: local
hooks:
- id: spotless
name: spotless check
language: unsupported
entry: ./gradlew spotlessCheck --quiet
pass_filenames: false
files: \.(java|kt|kts)$
# Dockerfile
- repo: https://github.com/hadolint/hadolint
rev: v2.15.1
hooks:
- id: hadolint # PATH の hadolint を使う
# Terraform
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.109.2
hooks:
- id: terraform_fmt
- id: terraform_validate
# TypeScript(型チェックは push 前に回す)
- repo: local
hooks:
- id: tsc
name: tsc --noEmit
language: unsupported
entry: npx tsc --noEmit
pass_filenames: false
types_or: [ts, tsx]
stages: [pre-push]
プロジェクト全体を見るツール(tsc・spotless・go vet など)は pass_filenames: false にします。 ファイル名を渡すと、ツールによっては設定ファイル(tsconfig.json など)を読まずに動きます。
stages と SKIP:いつ動かすか・飛ばすか
| stages の値 | 動くタイミング |
|---|---|
pre-commit |
コミットの前(既定) |
commit-msg |
メッセージを書いた後 |
pre-push |
push の前 |
prepare-commit-msg / post-commit / post-checkout / post-merge / post-rewrite / pre-merge-commit / pre-rebase |
それぞれの Git フック |
manual |
自動では動かない。--hook-stage manual で呼ぶ |
3.2.0 から、stages の値は Git のフック名と同じになりました。 以前の commit・push は、pre-commit migrate-config で pre-commit・pre-push に書き換えられました。
- id: mypy
stages: [manual] # 普段は動かさない
additional_dependencies: [types-requests]
pre-commit run mypy --hook-stage manual --all-files # 必要なときだけ
pre-commit run --hook-stage pre-push --all-files # pre-push のフックを試す
一時的に飛ばす方法です。
SKIP=ruff-check,ruff-format git commit -m "feat: add c" # 指定したフックだけ飛ばす
git commit --no-verify -m "..." # すべて飛ばす(Git の機能)
ruff check..............................................................Skipped
ruff format.............................................................Skipped
SKIP は id をカンマで区切って書きます。 --no-verify は commit-msg のフックも含めてすべて飛ばすので、SKIP のほうが範囲を絞れます。
コマンド一覧
| やりたいこと | コマンド |
|---|---|
| Git のフックを入れる | pre-commit install(種類を足す:--hook-type pre-push) |
| フックの環境も先に作る | pre-commit install --install-hooks または pre-commit install-hooks |
| 全ファイルに実行 | pre-commit run --all-files |
| 1つのフックだけ | pre-commit run ruff-check --all-files |
| ファイルを指定 | pre-commit run --files src/app.py |
| 差分だけ(CI 向け) | pre-commit run --from-ref origin/main --to-ref HEAD |
| 失敗時に差分を表示 | pre-commit run --all-files --show-diff-on-failure |
| rev を更新 | pre-commit autoupdate(1つだけ:--repo URL) |
| rev を SHA で固定 | pre-commit autoupdate --freeze |
| 設定の検査 | pre-commit validate-config |
| 以前の書き方を新しい書き方にする | pre-commit migrate-config |
| 使わない環境を消す | pre-commit gc(手元で 2 repo(s) removed.) |
| キャッシュを全部消す | pre-commit clean |
| フックを外す | pre-commit uninstall |
| 作ったフックを試す | pre-commit try-repo ../my-hooks my-hook-id --all-files |
autoupdate の注意
autoupdate は、各リポジトリの既定ブランチから辿れる最新のタグに更新します。 pre-commit のソースでは、git fetch origin HEAD --tags の後に git describe FETCH_HEAD --tags --abbrev=0 でタグを決めています。手元では、既定ブランチに含まれない gitleaks の v8.30.1 が v8.30.0 に下がりました。
[https://github.com/gitleaks/gitleaks] updating v8.30.1 -> v8.30.0
autoupdate の後は差分を確かめてからコミットします。--freeze を付けると、タグの代わりにコミットの SHA を書き、タグをコメントに残します。
pre-commit autoupdate --freeze --repo https://github.com/astral-sh/ruff-pre-commit
# [https://github.com/astral-sh/ruff-pre-commit] updating v0.15.0 -> v0.17.0 (frozen)
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 44b5042edab9382aba712eed4f9c7bab7a3d6a3e # frozen: v0.17.0
定期的な更新を自動化する方法は、関連記事「Dependabot・Renovate設定|目的別コピペ設定集と比較表」で扱っています。
CI(GitHub Actions)で動かす
手元でフックを入れていない人のコミットも、CI で同じチェックにかけます。actionlint 1.7.12 で指摘が無いことを確かめたワークフローです。
# .github/workflows/pre-commit.yml
name: pre-commit
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/setup-python@v7
with:
python-version: "3.13"
- uses: actions/cache@v6
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
- run: pip install pre-commit==4.7.0
- name: 変更されたファイルだけ(PR)
if: github.event_name == 'pull_request'
run: >
pre-commit run --show-diff-on-failure --color always
--from-ref "${{ github.event.pull_request.base.sha }}"
--to-ref "${{ github.event.pull_request.head.sha }}"
env:
SKIP: no-commit-to-branch,gitleaks-system
- name: すべてのファイル(main)
if: github.event_name == 'push'
run: pre-commit run --all-files --show-diff-on-failure --color always
env:
SKIP: no-commit-to-branch,gitleaks-system
| ポイント | 理由 |
|---|---|
| キャッシュのキーに設定ファイルのハッシュ | rev を変えたときだけ環境を作り直す。手元では9リポジトリで約250MB |
fetch-depth: 0 |
--from-ref で比べるコミットを取得するため |
--show-diff-on-failure |
自動修正されたフックの差分をログに出す |
SKIP: no-commit-to-branch |
main への push で動く CI で失敗させないため |
SKIP: gitleaks-system |
CI では --staged の差分が無いので、履歴を調べる別のステップにする |
キャッシュのキーの考え方は、関連記事「GitHub Actionsのキャッシュとmatrix|コピペ用YAMLとキー設計」で扱っています。秘密情報や脆弱性の検査を CI に足す例は、関連記事「Trivyの使い方|脆弱性スキャン・SBOM出力とGitHub Actions設定」で扱っています。
遅いときの対策
手元の小さなリポジトリで --verbose を付けると、フックごとの時間が出ました。
check for case conflicts - duration: 0.51s
prettier - duration: 0.39s
Validate GitHub Workflows - duration: 0.66s
Detect hardcoded secrets - duration: 0.9s
ruff check - duration: 0.02s
ruff format - duration: 0.01s
| 原因 | 対策 |
|---|---|
| 初回の環境づくりに時間がかかる | pre-commit install --install-hooks を最初に1回。CI は ~/.cache/pre-commit をキャッシュ |
| 型チェック・テストなど重いフック | stages: [pre-push] か [manual] に移す |
| 対象外のファイルまで見ている | files・exclude・types で絞る。生成物・vendor は最上位の exclude |
| 遅いツールを使っている | flake8+isort+black を ruff にまとめるなど、速いツールに置き換える |
require_serial: true のフック |
並列に分けられない。対象のファイルを絞る |
| 1つ失敗したら後は見なくてよい | fail_fast: true |
git commit では、ステージしたファイルだけが対象です。 手元では、1ファイルを --files で指定した実行が 2.0秒、全ファイルが 3.2〜5.0秒でした。
よくあるつまずき
| 症状 | 原因 | 直し方 |
|---|---|---|
| フックが動かない | pre-commit install をしていない(clone し直した・別の PC) |
pre-commit install。commit-msg などは default_install_hook_types に足す |
`pre-commit` not found. Did you forget to activate your virtualenv? |
install したときの仮想環境を消した | pipx などで入れ直して pre-commit install |
| 毎回 Failed になる | 自動修正の結果を git add していない |
直った内容を確かめて git add |
[WARNING] Stashed changes conflicted with hook auto-fixes... Rolling back fixes... |
ステージしていない変更と、フックの修正がぶつかった | 先に全部ステージするか、変更を分けてコミット |
Missing required key: rev |
rev の書き忘れ | rev: を書く(autoupdate で入る) |
accepts at most 1 arg(s) |
ファイル名を受け取らないツールにファイル名が渡った | pass_filenames: false |
| golang のフックの環境づくりで失敗 | 手元の Go が go.mod の求める版より前 | Go を更新するか、*-system のフックとバイナリを使う |
Git のフックを npm の仕組みで管理する husky・lefthook との比較は、関連記事「Git hooks・husky v9の設定方法|実行結果とlefthook比較」で扱っています。
よくある質問
Q. husky と pre-commit はどちらを使えばよいですか?
A. pre-commit は、フックごとに言語の環境を自動で作り、版を設定ファイルで固定できます。Python や複数の言語が混ざるリポジトリで使いやすい作りです。husky は npm の prepare で入り、Node.js のプロジェクトで package.json と一緒に管理しやすい作りです。
Q. フックの rev はタグと SHA のどちらで書きますか?
A. タグは付け替えられるので、改ざんへの備えを強めたいときは autoupdate --freeze で SHA にします。読みやすさはタグが上です。
Q. pre-commit.ci とは何ですか?
A. pre-commit の作者が運営する CI のサービスで、PR ごとにフックを動かし、自動修正をコミットしたり、autoupdate の PR を作ったりします(pre-commit.ci のサイトより)。設定は .pre-commit-config.yaml の ci: キーに書きます。この記事のように GitHub Actions で動かす方法もあります。
まとめ
sample-config→autoupdate→install→run --all-filesの順で始める- 自動修正したフックも Failed になる。直った内容を
git addして再コミット - commit-msg・pre-push のフックは
default_install_hook_typesに足す - 重いフックは
stages: [pre-push]か[manual]、一時的にはSKIP=id1,id2 autoupdateは既定ブランチの最新タグ。版が下がることがあるので差分を見るgitleaks-systemはpass_filenames: false。CI では履歴を調べる別のステップ- CI は
~/.cache/pre-commitを設定ファイルのハッシュでキャッシュし、PR は--from-ref・--to-ref language: systemは 4.4.0 からunsupportedという名前
参考・出典
確認日はいずれも 2026年10月13日です。
- pre-commit 公式サイト:https://pre-commit.com/
- pre-commit(GitHub、CHANGELOG・ソース):https://github.com/pre-commit/pre-commit
- PyPI「pre-commit」4.7.0:https://pypi.org/project/pre-commit/
- pre-commit/pre-commit-hooks v6.0.0:https://github.com/pre-commit/pre-commit-hooks
- astral-sh/ruff-pre-commit:https://github.com/astral-sh/ruff-pre-commit
- rbubley/mirrors-prettier:https://github.com/rbubley/mirrors-prettier
- gitleaks/gitleaks(.pre-commit-hooks.yaml):https://github.com/gitleaks/gitleaks
- shellcheck-py/shellcheck-py:https://github.com/shellcheck-py/shellcheck-py
- python-jsonschema/check-jsonschema:https://github.com/python-jsonschema/check-jsonschema
- compilerla/conventional-pre-commit:https://github.com/compilerla/conventional-pre-commit
- pre-commit.ci:https://pre-commit.ci/
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「pre-commit設定|.pre-commit-config.yamlとフック一覧」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。