Git Pre-commit Hook — Stagedファイルの自動Lint&Format
Husky不要の軽量Gitフック構築:ステージされたファイルのMarkdown自動フォーマット、コードLint、Mermaid構文チェック。
プロジェクト開発において、コミット前にコードの品質やドキュメントの書式を担保することは重要です。サードパーティの重いツールを導入しなくても、Git ネイティブの Git Hooks と core.hooksPath を利用することで、ゼロ依存の自動検証パイプラインを構築できます。
flowchart TD
Start(["開発者が git commit -m '...' を実行"]) --> Hook[".githooks/pre-commit が起動"]
Hook --> Step1{"1. ステージ済み Markdown を確認<br/>(.md, .mdx)"}
Step1 -->|対象あり| Formatter["agent-md format を実行<br/>変更を git add"]
Step1 -->|なし| Step2{"2. ステージ済みソースコードを確認<br/>(.ts, .tsx, .astro...)"}
Formatter --> Step2
Step2 -->|対象あり| Linter["bun lint (ESLint) を実行<br/>変更を git add"]
Step2 -->|なし| Step3{"3. ステージ済みドキュメント・図を確認"}
Linter --> Step3
Step3 -->|対象あり| MermaidLinter["bun lint:mermaid (maid) を実行"]
Step3 -->|なし| Done(["コミット完了 ✅"])
MermaidLinter -->|構文エラーあり| Abort(["コミット中断 ❌<br/>エラー修正が必要"])
MermaidLinter -->|正常| Done
なぜ Husky ではなく Git Native Hook なのか?#
flowchart LR
subgraph HuskyApproach["Husky を使う場合"]
H1["npm パッケージのインストールが必要"]
H2["node_modules の肥大化"]
H3["外部 Node.js ラッパーへの依存"]
end
subgraph NativeApproach["Git Native Hook (core.hooksPath)"]
N1[".githooks/ 配下のシェルスクリプト1つ"]
N2["依存関係ゼロ (Zero Dependencies)"]
N3["リポジトリ内でチーム共有可能"]
end
| 比較項目 | Husky / 外部ライブラリ | Git Native Hook (core.hooksPath) |
|---|---|---|
| 依存関係 | npm パッケージの追加が必要 | ゼロ依存 |
| 実行速度 | Node ラッパーの起動オーバーヘッド | 即時実行されるシェルスクリプト (<10ms) |
| チーム共有 | 可能 | 可能(Git 管理下) |
Pre-commit スクリプトの実装#
.githooks/pre-commit に以下の内容を記述します:
#!/usr/bin/env bash
set -e
# 1. Format staged markdown files with agent-md if available
if command -v agent-md >/dev/null 2>&1; then
STAGED_MD_FILES=$(git diff --cached --name-only --diff-filter=d | grep -E '\.(md|mdx)$' || true)
if [ -n "$STAGED_MD_FILES" ]; then
echo "[git-hook] Running agent-md format on staged markdown files..."
for file in $STAGED_MD_FILES; do
if [ -f "$file" ]; then
agent-md "$file"
git add "$file"
fi
done
fi
fi
# 2. Lint changed code files with bun lint
STAGED_CODE_FILES=$(git diff --cached --name-only --diff-filter=d | grep -E '\.(js|jsx|ts|tsx|astro)$' || true)
if [ -n "$STAGED_CODE_FILES" ]; then
echo "[git-hook] Running bun lint on staged code files..."
bun lint
for file in $STAGED_CODE_FILES; do
if [ -f "$file" ]; then
git add "$file"
fi
done
fi
# 3. Lint mermaid diagrams with bun lint:mermaid
STAGED_DOC_FILES=$(git diff --cached --name-only --diff-filter=d | grep -E '\.(md|mdx|html|astro)$' || true)
if [ -n "$STAGED_DOC_FILES" ]; then
echo "[git-hook] Running bun lint:mermaid on diagrams..."
bun lint:mermaid
fibashロジックのポイント#
1. git diff --cached によるステージングファイルの絞り込み#
flowchart LR
GitIndex["Git Index(ステージング領域)"] --> Filter["git diff --cached --name-only --diff-filter=d"]
Filter --> Regex["grep -E '\\.(拡張子)$'"]
Regex --> Files["対象ファイル一覧"]
--cached:git addされたステージング対象のみを抽出します。--diff-filter=d: 削除されたファイルを除外し、存在しないファイルへのアクセスエラーを防ぎます。set -e: エラー発生時にスクリプトを即時停止し、不正な状態でのコミットを防ぎます。
2. フォーマット後の自動ステージング#
agent-md や eslint --fix でコードが自動修正された場合、git add "$file" で修正内容をそのまま今回のコミットに自動反映します。
プロジェクトへの自動適用設定#
package.json に prepare スクリプトを追加します:
{
"scripts": {
"prepare": "git config core.hooksPath .githooks",
"lint": "eslint --fix 'src/**/*.{js,ts,jsx,tsx,astro}'",
"lint:mermaid": "maid docs/ src/"
}
}json実行権限を付与:
chmod +x .githooks/pre-commit
bun run preparebashまとめ#
シンプルなシェルスクリプトを1つ用意するだけで:
- Markdown ドキュメントの自動整形
- ソースコードの Lint チェック
- Mermaid 図の構文検証
をコミット時に完全自動化できます。