更新: 2026年03月 · 11 分で読める · 5,442 文字
git hooksで pre-commit を自動化し、コミット品質を上げる実践ガイド
本記事では、git hooks の pre-commit フェーズを活用して、コード品質チェック・フォーマット検証・テスト実行を自動化する方法を解説します。開発チーム全体でコミット基準を統一でき、品質低下やリスク要因を事前に防げます。
git hooks と pre-commit が解決する課題
開発チームでよく起こる問題として「未フォーマットのコードがコミットされる」「lint エラーが本番環境で検出される」「テストを実行せずにマージされる」といったことが挙げられます。git hooks の pre-commit フェーズを活用すれば、コミット直前に自動チェックを実行でき、こうした課題を根本的に解決できます。
git hooks は Git リポジトリの .git/hooks ディレクトリに配置されるスクリプトで、特定のイベント(コミット前、プッシュ前など)時に自動実行されます。pre-commit フェーズは「コミットが作成される直前」に動作するため、問題があればコミット自体をブロックできます。
pre-commit フレームワークを使った実装方法
手作業で shell スクリプトを書くこともできますが、実務では pre-commit フレームワーク を導入するのが一般的です。複数の言語・ツールに対応し、設定ファイルで管理でき、チーム全体で自動的に同じルールを適用できます。
インストールと初期設定
まず、pre-commit をインストールしましょう。Python 環境が必要です。
# pip または poetry で pre-commit をインストール
pip install pre-commit
# または
poetry add --group dev pre-commit
# pre-commit のバージョン確認
pre-commit --version
次に、プロジェクトルートに .pre-commit-config.yaml ファイルを作成します。このファイルで実行するチェックを定義します。
# .pre-commit-config.yaml
repos:
# Python フォーマッター (Black)
- repo: https://github.com/psf/black
rev: 24.1.1
hooks:
- id: black
language_version: python3.11
# Python linter (Ruff)
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.0
hooks:
- id: ruff
args: [--fix]
# YAML フォーマッター
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-merge-conflict
# Git デフォルト
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
- id: prettier
types_or: [javascript, jsx, typescript, json, yaml, markdown]
その後、Git フックを実際にセットアップします。
# pre-commit フックをインストール
pre-commit install
# フックがインストールされたか確認
ls -la .git/hooks/ | grep pre-commit
初回実行時に全ファイルをスキャン
既存プロジェクトの場合、初回実行時に過去のコミットまでスキャンすることで、徐々に品質を向上させられます。
# 全ファイルを対象に pre-commit を実行
pre-commit run --all-files
# 特定のフックだけ実行したい場合
pre-commit run black --all-files
実践的なカスタマイズ例
JavaScript / TypeScript プロジェクト向け設定
Node.js ベースのプロジェクトでよく使われる組み合わせです。
# .pre-commit-config.yaml
repos:
# ESLint
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.55.0
hooks:
- id: eslint
types: [javascript, jsx, typescript, tsx]
args: [--fix]
# Prettier (コード整形)
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
- id: prettier
types_or: [javascript, jsx, typescript, json, yaml]
# 共通チェック
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-json
- id: check-merge-conflict
- id: detect-private-key
Python プロジェクト向けの高度な設定
型チェック、テスト実行、複数の linter を組み合わせた例です。
# .pre-commit-config.yaml
repos:
# Black (フォーマッター)
- repo: https://github.com/psf/black
rev: 24.1.1
hooks:
- id: black
language_version: python3.11
args: [--line-length=100]
# Ruff (高速 linter)
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.0
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
# mypy (型チェック)
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
args: [--ignore-missing-imports]
additional_dependencies: [types-all]
# Bandit (セキュリティチェック)
- repo: https://github.com/PyCQA/bandit
rev: 1.7.5
hooks:
- id: bandit
args: [-c, pyproject.toml]
additional_dependencies: [bandit[toml]]
# 共通チェック
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
- id: debug-statements
- id: detect-private-key
よくあるハマりポイントと解決策
「フックが実行されない」場合
pre-commit install を実行していない場合が多いです。まず以下を確認してください。
# フックファイルが正しく生成されているか確認
cat .git/hooks/pre-commit
# 実行権限があるか確認
ls -l .git/hooks/pre-commit
# 権限がない場合は追加
chmod +x .git/hooks/pre-commit
「特定の言語のツールがインストールされていない」エラー
pre-commit は各ツールを独立した環境に自動インストールします。しかし稀にシステム依存関係が不足する場合があります。
# キャッシュをクリアして再実行
pre-commit clean
# フックを再インストール
pre-commit install --install-hooks
# キャッシュをリセット
pre-commit run --all-files --hook-stage commit
「コミットをスキップしたい」場合
緊急時にフックを一時的にバイパスできます(ただし チーム内では慎重に)。
# pre-commit フックをスキップしてコミット
git commit --no-verify
# または環境変数で指定
SKIP=black,ruff git commit -m "message"
「パフォーマンスが遅い」場合
ファイル数が多い場合、pre-commit の実行時間が長くなります。以下の最適化を試してください。
# .pre-commit-config.yaml
repos:
- repo: https://github.com/psf/black
rev: 24.1.1
hooks:
- id: black
language_version: python3.11
# ステージを分けて、コミット時は簡易チェックのみ
stages: [commit]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.0
hooks:
- id: ruff
args: [--fix]
# 特定のファイルのみチェック対象
exclude: ^(migrations/|tests/)
チーム内での運用方法
.pre-commit-config.yaml をリポジトリに含めることで、開発者全員が同じルールを自動適用できます。
# リポジトリに設定ファイルを含める
git add .pre-commit-config.yaml
git commit -m "Add pre-commit hooks configuration"
# README に セットアップ手順を記載
# 以下を README.md に追加:
# ## Development Setup
# 1. Install pre-commit: pip install pre-commit
# 2. Setup hooks: pre-commit install
# 3. Run initial check: pre-commit run --all-files
新しいメンバーが clone した後、以下を実行するだけで自動的に環境が整います。
# 新メンバーのセットアップ
git clone
cd
pre-commit install
pre-commit run --all-files
pre-commit 以外の選択肢との比較
Husky(Node.js)など他のツールもありますが、pre-commit フレームワークの利点は「言語に依存しない」「設定ファイルで一元管理」「公開されたフック レジストリが豊富」の3点です。Python プロジェクトなら pre-commit が、Node.js オンリーなら Husky が候補になります。
使うべき場面と使うべきでない場面
使うべき場面:
- 複数人で開発するチームプロジェクト
- コード品質基準が決まっている場合
- 自動テスト、型チェック、セキュリティスキャンを必須にしたい場合
使うべきでない場面:
- 個人の学習用スクリプト
- チェック項目が不安定で頻繁に変わる場合(フックの追加・削除で混乱する)
- レガシープロジェクトで過度な制約を避けたい場合
よくある質問
いいえ。pre-commit install を実行していない場合、フックは動作しません。チーム全体に導入する場合は、README や CI/CD パイプラインで確実に install させる仕組みが必要です。
問題です。--no-verify は緊急時のみ使用すべきで、習慣的に使うと品質ルールが形骸化します。むしろ「なぜ制約が必要なのか」チーム内で再認識し、不適切なルールはコンセンサスで廃止することをお勧めします。
.pre-commit-config.yaml を編集した後、pre-commit install --install-hooks を実行すれば、最新の設定が反映されます。古い hook は自動削除されないため、必要に応じて pre-commit clean で一度リセットしてください。
まとめ
- git hooks の pre-commit フェーズを活用することで、コミット前の自動チェックが可能になり、チーム全体のコード品質を向上させられる
- pre-commit フレームワークを導入すれば、設定ファイル一つで複数のツール(Black、ESLint、mypy など)を一元管理でき、チーム全体で統一されたルールを適用できる
- 初期セットアップは pre-commit install と .pre-commit-config.yaml の作成のみで、その後は自動的に全開発者に同じルールが適用される
- パフォーマンスが課題の場合は exclude で対象ファイルを限定した
おすすめGitリソース
- Pro Git Book Official free Git book. From basics to advanced topics.
- GitHub Docs Official GitHub documentation including PR/Issue workflows.
- Learn Git Branching Interactive tool to visually learn branch operations.