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期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?