はじめに
Gitフックは、Gitライフサイクルの特定の時点で自動実行されるスクリプトです。多くの開発者はコードフォーマットやリンティングだけに利用していますが、その可能性はワークフロー自動化、プロジェクト管理、チームコラボレーションへと広がります。本記事では、Gitフックを活用した包括的な自動化戦略を解説します。
Gitフックの基礎
Gitフックは各リポジトリの .git/hooks/ ディレクトリに配置されます。bash、Python、Node.js、Rubyなど、任意の言語で記述可能な実行可能スクリプトです。フックはクライアントサイドフック(pre-commit、pre-push、commit-msg)とサーバーサイドフック(pre-receive、update、post-receive)に分類されます。
コミット時のフック実行順序は pre-commit → commit-msg → post-commit です。プッシュ時は pre-push(クライアント)→ pre-receive → update → post-receive(サーバー)の順に実行されます。
Huskyによるフック管理
.git/hooks/ に手動でスクリプトを配置する方法は、そのディレクトリがGit管理外であるためチーム共有に適しません。Huskyはフックをリポジトリ内で管理し、チーム全体で共有できるようにします。
Husky v9+のインストール:
npx husky init
.husky/ ディレクトリにフックスクリプトを作成します:
# .husky/pre-commit
npx lint-staged
CI環境では HUSKY=0 でフックをスキップできます:
HUSKY=0 git push
lint-stagedとの連携
lint-stagedはステージングされたファイルのみに対してリンターを実行し、高速なチェックを実現します:
{
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{css,scss}": ["stylelint --fix", "prettier --write"]
}
}
Pre-Commitフック:第一防衛線
Pre-commitフックは各コミット前に実行され、高速なローカルチェックに適しています。
| チェック種別 | ツール | 目的 |
|---|---|---|
| リンティング | ESLint, stylelint | コードスタイルの統一 |
| フォーマット | Prettier, dprint | 一貫した自動整形 |
| 型チェック | TypeScript --noEmit | 型エラーの早期発見 |
| シークレット検出 | secretlint, truffleHog | 認証情報の漏洩防止 |
| ファイル検証 | カスタムスクリプト | 巨大ファイルやTODOのブロック |
包括的なpre-commit設定例:
# .husky/pre-commit
npx lint-staged
npx tsc --noEmit
npx secretlint "**/*"
パフォーマンスは重要です。pre-commitフックは5秒以内に完了するよう設計し、開発の流れを妨げないようにしましょう。
Pre-Pushフック:CIのセーフティネット
Pre-pushフックはコードがリモートリポジトリに到達する前に実行され、より時間のかかる検証に適しています:
# .husky/pre-push
npm test
npm run build
npm audit
ブランチ名の検証で命名規則を強制します:
#!/bin/sh
branch=$(git rev-parse --abbrev-ref HEAD)
if ! echo "$branch" | grep -qE '^(feature|bugfix|hotfix)/[A-Z]+-[0-9]+-'; then
echo "エラー: ブランチ名は feature/ABC-123-形式に従ってください"
exit 1
fi
commitlintによるコミットメッセージ検証
Conventional Commits形式の強制により、一貫性のある解析可能な履歴を実現します:
# .husky/commit-msg
npx --no -- commitlint --edit $1
commitlintの設定:
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'subject-max-length': [2, 'always', 50],
'body-max-line-length': [2, 'always', 72],
},
};
CI同等性戦略
フックとCIが同一のチェックを実行することが最も堅牢なパターンです。共有スクリプトを抽出し、両方の環境から呼び出します:
#!/bin/sh
# scripts/validate.sh - フックとCIの両方から呼び出される
npm run lint
npm run typecheck
npm test
ローカルフックは警告や自動修正を行い、CIは厳格に強制するという段階的アプローチが効果的です。
結論
Gitフックはコードフォーマットを超えた強力な自動化レイヤーです。Huskyとlint-stagedの組み合わせがほとんどのプロジェクトで推奨されるベースラインです。Pre-pushフックはCIに到達する前のセーフティネットを提供し、commitlintはクリーンなコミット履歴を保証します。最終目標は、自動化が反復的なチェックを処理し、開発者がロジックと設計に集中できる環境を実現することです。
