OllamaをGitのpre-commitフックに組み込む方法|ローカルLLMでコードレビューとコミットメッセージ生成を自動化する

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)ローカルLLM > OllamaをGitのpre-commitフックに組み込む方法|ローカルLLMでコードレビューとコミットメッセージ生成を自動化する
「コードを書くたびに手動でレビューする時間が取れない」
「コミットメッセージを後から見返すと何の変更か分からないものばかり残っている」

そんな悩みを抱える開発者・インフラエンジニアは多いはずです。この記事では、Ollamaをgit pre-commitフックに組み込み、コミット前にローカルLLMが自動でコードをレビューし、問題があればコミットをブロックする仕組みを解説します。さらに、コミットメッセージの下書きを自動生成する prepare-commit-msg フックの実装まで一気通貫で説明します。
APIキー不要・インターネット不要。機密コードを外部サービスに一切送らず、手元のLinuxサーバー(またはWSL2環境)だけで完結します。

この記事のポイント

・`git diff --cached | curl http://localhost:11434/api/generate` の組み合わせだけでローカルLLMレビューが動く
・exitコードで制御するため、問題検出時に `git commit` を自動ブロックできる
・`prepare-commit-msg` フックを追加すればコミットメッセージの下書きも自動生成される
・`.pre-commit-config.yaml` で管理することでチーム全員に同じフックを展開できる


OllamaをGitのpre-commitフックに組み込む方法|ローカルLLMでコードレビューとコミットメッセージ生成を自動化する

「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

git pre-commitフックにOllamaを組み込む利点

git pre-commitフックは、`git commit` の実行前に任意のスクリプトを走らせる仕組みです。Lint・テスト・フォーマット統一などに使われることが多いですが、外部HTTP APIを呼び出すことも当然できます。
OllamaはREST APIを標準で提供しています。`curl` 1本で差分を送信しレビュー結果を受け取れるため、シェルスクリプトだけで「コードをAIに見せてからコミットする」仕組みが作れます。

クラウドのコードレビューサービスと比べた最大のメリットは、ソースコードが一切外部に出ない点です。NDA締結案件・金融系・医療系など、ソースコードのクラウドアップロード自体が社内ポリシーで禁止されているプロジェクトでも導入できます。
また、毎月の従量課金も発生しません。Ollamaサーバーが1台あれば、チーム全員のコミットレビューをコスト0で処理できます。

前提として、Ollamaがすでに稼働していることが必要です。構築がまだの方は Ubuntu ServerでのOllama構築ガイド を先に確認してください。

前提環境の確認とモデル選定

1. Ollamaの起動確認

pre-commitフックはコミットをブロックするため、Ollamaに接続できない状態でフックが走ると開発者が詰まります。まず接続確認をしておきます。

# Ollama APIにアクセスできるか確認する $ curl http://localhost:11434/api/tags # モデルが取得済みの場合の出力例 {"models":[{"name":"phi4:latest","model":"phi4:latest","modified_at":"2026-08-10T12:00:00Z","size":4897626752,"digest":"abc123...","details":{"parent_model":"","format":"gguf","family":"phi3","families":["phi3"],"parameter_size":"14.7B","quantization_level":"Q4_K_M"}}]}

`curl` が応答を返せばOKです。接続に失敗する場合は `systemctl status ollama` でサービス状態を確認してください。

2. コードレビュー向けモデルを選ぶ

pre-commitフックはコミットをブロックしている間、開発者が待ち続けます。そのため応答速度が品質と同じくらい重要です。
モデルを選ぶ目安は次のとおりです: ・Phi-4(`phi4:latest`): 14Bパラメータ。コード理解力が高く8GB VRAMで動く。速度と品質のバランスが最も良い。推奨
・Mistral(`mistral:7b-instruct-q4_0`): 7B。速度重視。4GB VRAMで動作。高速だが複雑なバグは見逃す場合がある
・Llama3.3(`llama3.3:70b-instruct-q4_0`): 70B。品質最高だが応答に10~30秒かかるためCIでの利用向き

Phi-4とMistralをpullしておきます:

$ ollama pull phi4 pulling manifest... pulling fa8235e5b48f... 100% 8.1 GB pulling e5a87f6f2099... 100% 1.2 KB success $ ollama pull mistral:7b-instruct-q4_0 pulling manifest... pulling 3b4510ab5a12... 100% 4.1 GB success

各モデルの詳細な性能比較については ローカルLLMのモデルを比較する方法 も参照してください。

基本的なpre-commitフックを作成する

1. .git/hooks/pre-commitファイルを確認・作成する

gitリポジトリのルートで作業します。`.git/hooks/` には `.sample` 拡張子のサンプルファイルが並んでいます。

$ ls .git/hooks/ applypatch-msg.sample commit-msg.sample fsmonitor-watchman.sample post-update.sample pre-applypatch.sample pre-commit.sample pre-merge-commit.sample pre-push.sample pre-rebase.sample pre-receive.sample prepare-commit-msg.sample update.sample # pre-commit.sampleをコピーして使う場合 $ cp .git/hooks/pre-commit.sample .git/hooks/pre-commit # ゼロから作る場合(こちらを推奨) $ cat /dev/null > .git/hooks/pre-commit

2. Ollama APIへdiffを送信するスクリプトを書く

以下が基本的なスクリプトです。`git diff --cached` でステージ済みの差分を取得し、JSONエスケープしてOllama APIに送ります。
Pythonの `json.dumps` を使ってエスケープすることで、差分内のダブルクォートやバックスラッシュが原因のJSON破損を防ぎます。

#!/bin/bash set -e OLLAMA_URL="http://localhost:11434/api/generate" MODEL="${OLLAMA_REVIEW_MODEL:-phi4}" MAX_DIFF_LINES=200 # ステージ済み差分を取得(Python・Shell・JSのみ対象) DIFF=$(git diff --cached --diff-filter=ACMR -- '*.py' '*.sh' '*.js' '*.ts' | head -n ${MAX_DIFF_LINES}) # 差分がなければスキップ(バイナリファイルのみ変更等) if [ -z "${DIFF}" ]; then exit 0 fi # Ollamaへの接続確認(タイムアウト2秒) if ! curl -s --connect-timeout 2 "${OLLAMA_URL%/api/generate}/api/tags" > /dev/null 2>&1; then echo "[OllamaレビューBot] Ollamaに接続できません。スキップします。" exit 0 fi # プロンプトをJSONエスケープして送信 PROMPT="以下のgit差分をレビューしてください。セキュリティ問題・明らかなバグ・危険なコードがある場合は「BLOCK: 問題の要約(1行・日本語)」を最初の行に書いてください。問題がなければ最初の行に「OK」とだけ書いてください。\n\n${DIFF}" ESCAPED=$(printf '%s' "${PROMPT}" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))") RESPONSE=$(curl -s "${OLLAMA_URL}" \ -H "Content-Type: application/json" \ -d "{\"model\":\"${MODEL}\",\"prompt\":${ESCAPED},\"stream\":false}" \ | python3 -c "import sys,json; data=json.load(sys.stdin); print(data.get('response','').strip())") FIRST_LINE=$(echo "${RESPONSE}" | head -n 1) if echo "${FIRST_LINE}" | grep -q "^BLOCK:"; then echo "" echo "⚠ OllamaレビューBot がコミットをブロックしました:" echo "--------------------------------------------" echo "${RESPONSE}" echo "--------------------------------------------" echo "修正後に git add → git commit をやり直してください。" echo "緊急時は git commit --no-verify でスキップできます。" exit 1 fi echo "[OllamaレビューBot] ${FIRST_LINE}" exit 0

`OLLAMA_REVIEW_MODEL` 環境変数で実行時にモデルを切り替えられるようにしています。通常はPhi-4、速度重視の場面ではMistralに切り替えられます。

3. 実行権限を付与して動作確認する

# スクリプトを書き込んだ後、実行権限を付与する $ chmod +x .git/hooks/pre-commit # 動作確認(ダミーの変更でテスト) $ echo "x = 1" >> test.py $ git add test.py $ git commit -m "テスト" # Ollamaのレビューが走る [OllamaレビューBot] OK [master abc1234] テスト 1 file changed, 1 insertion(+)

問題ない変更は `OK` と表示されてコミットが通ります。逆に問題があれば `BLOCK:` で始まるメッセージが出力されコミットがキャンセルされます。

コードの問題点を検出してコミットをブロックする

1. レビュー指示プロンプトを設計する

`BLOCK:` / `OK` の二択で返答させるのがポイントです。LLMは自由に出力させると長い説明文を返します。「最初の行で判定を示す」という構造にするとスクリプトで判定しやすくなります。

プロンプトをチューニングする際のポイント: ・「セキュリティ上の重大な問題に限定」と明記する(偽陽性削減)
・具体例として「ハードコードされた認証情報、SQLインジェクション、eval()へのユーザー入力直渡し」を列挙する
・「コードスタイルの好みや軽微なリファクタリング提案はBLOCKにしないこと」と明記する

より精密なプロンプト例:

PROMPT="あなたはセキュリティレビュアーです。以下のgit差分を確認し、\ 次の条件に1つでも該当する場合のみ「BLOCK: 問題の要約(日本語・1行)」を最初の行に出力してください。\ 条件: (1)ハードコードされたパスワード・APIキー・秘密鍵 (2)SQLインジェクションの可能性 \ (3)ユーザー入力をサニタイズせずにeval()・exec()・shell_exec()に渡している \ (4)HTTPSでなくHTTPで機密情報を送信している。\ 上記に該当しない場合は最初の行に「OK」とだけ書いてください。\n\n${DIFF}"

2. 問題検出パターンを確認する

実際にブロックされる例を確認します。以下のコードをステージするとブロックが発動します:

# 意図的にパスワードをハードコードしたファイルで確認 $ cat > danger.py << 'EOF' DB_PASSWORD = "SuperSecret123" def connect_db(): return connect(host="db.example.com", password=DB_PASSWORD) EOF $ git add danger.py $ git commit -m "DBコネクタ追加" # Ollamaがブロック ⚠ OllamaレビューBot がコミットをブロックしました: -------------------------------------------- BLOCK: ハードコードされたパスワードが含まれています(DB_PASSWORD) パスワードはコードに直書きせず、環境変数または秘密管理サービスから取得してください。 -------------------------------------------- 修正後に git add → git commit をやり直してください。 緊急時は git commit --no-verify でスキップできます。

コミットがキャンセルされ、開発者はその場で修正できます。`git commit --no-verify` は緊急時の逃げ道として用意しておき、使った場合はチームに報告するルールにしておくと運用しやすくなります。

prepare-commit-msgフックでコミットメッセージを自動生成する

pre-commitフックとは別に、`prepare-commit-msg` フックを使うとコミットメッセージの下書きを自動生成できます。エディタが開く前にAIが書いた内容が入っているので、確認・修正してそのままコミットするだけです。

1. フックファイルを作成する

$ cat > .git/hooks/prepare-commit-msg << 'HOOK' #!/bin/bash COMMIT_MSG_FILE=$1 COMMIT_SOURCE=$2 # --amend・merge・squash時はスキップ(既存メッセージを上書きしない) if [ -n "${COMMIT_SOURCE}" ]; then exit 0 fi DIFF=$(git diff --cached --diff-filter=ACMR | head -n 100) if [ -z "${DIFF}" ]; then exit 0 fi # Ollamaへの接続確認 if ! curl -s --connect-timeout 2 http://localhost:11434/api/tags > /dev/null 2>&1; then exit 0 fi PROMPT="以下のgit差分からConventional Commits形式のコミットメッセージを英語1行で生成してください。\ 形式: type(scope): description(例: feat(auth): add JWT validation to login endpoint)\ typeはfeat/fix/refactor/docs/chore/testから選んでください。descriptionは50文字以内。\n\n${DIFF}" ESCAPED=$(printf '%s' "${PROMPT}" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))") GENERATED=$(curl -s http://localhost:11434/api/generate \ -H "Content-Type: application/json" \ -d "{\"model\":\"${OLLAMA_REVIEW_MODEL:-phi4}\",\"prompt\":${ESCAPED},\"stream\":false}" \ | python3 -c "import sys,json; data=json.load(sys.stdin); print(data.get('response','').strip().split('\n')[0])") if [ -z "${GENERATED}" ]; then exit 0 fi # エディタに表示する内容(AI生成メッセージ + コメント) CURRENT=$(cat "${COMMIT_MSG_FILE}") { echo "${GENERATED}" echo "" echo "# [AI生成] 上の行を確認・編集してからエディタを保存・終了してください" echo "${CURRENT}" } > "${COMMIT_MSG_FILE}" HOOK $ chmod +x .git/hooks/prepare-commit-msg

2. 生成内容を確認・編集してコミットする

$ git add src/auth/login.py $ git commit # エディタが開く(vimの場合) # ---------------------------------------- feat(auth): add JWT token validation to login endpoint # [AI生成] 上の行を確認・編集してからエディタを保存・終了してください # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Changes to be committed: # modified: src/auth/login.py # ---------------------------------------- # 内容が適切であればそのまま :wq で保存 [master d4f812c] feat(auth): add JWT token validation to login endpoint 1 file changed, 34 insertions(+), 2 deletions(-)

AI生成のメッセージが的外れな場合はその場で書き直せます。90%以上の精度で意味のある下書きが生成されるため、メッセージを考える時間が大幅に短縮されます。

pre-commitフレームワークでチーム展開する

個人のローカル `.git/hooks/` に置いたスクリプトはgit管理されないため、新しいチームメンバーには自動で配布されません。`pre-commit` フレームワークを使うと `.pre-commit-config.yaml` としてリポジトリで管理でき、`pre-commit install` 1コマンドで展開できます。

1. pre-commitをインストールする

# pip でインストール $ pip install pre-commit # または pipx を使う場合(推奨) $ pipx install pre-commit $ pre-commit --version pre-commit 3.8.0

2. Ollamaフックをrepoに配置して定義ファイルを作る

プロジェクトルートに `scripts/ollama-review.sh` として先ほどのスクリプトを配置し、`.pre-commit-config.yaml` を作成します:

# scripts/ollama-review.sh としてスクリプトを配置 $ mkdir -p scripts $ cp .git/hooks/pre-commit scripts/ollama-review.sh $ chmod +x scripts/ollama-review.sh $ git add scripts/ollama-review.sh # .pre-commit-config.yaml を作成 $ cat > .pre-commit-config.yaml << 'EOF' repos: - repo: local hooks: - id: ollama-code-review name: "Ollama Code Review (local LLM)" language: script entry: scripts/ollama-review.sh stages: [pre-commit] pass_filenames: false always_run: false EOF # チームメンバー向けのインストール手順 $ pre-commit install pre-commit installed at .git/hooks/pre-commit

3. チームへの展開手順

`README.md` に以下を追記しておくと新メンバーが迷いません: ・`pip install pre-commit` を実行する
・`pre-commit install` を実行する
・Ollamaが手元で動いていない場合は `export OLLAMA_SKIP=1` でスキップできる(スクリプト内に `[ -n "$OLLAMA_SKIP" ] && exit 0` を追加する)

チーム共有のOllamaサーバーを立てている場合は、`OLLAMA_URL` を環境変数に分離することでメンバー全員が同じサーバーを使えます。チームへのローカルLLM共有サーバーの展開については 社内ChatGPT代替としてのローカルLLM選択肢 も参考にしてください。

CI/CDとの役割分担と実運用のポイント

pre-commitフックとCI/CDは補完関係にあります。役割を明確に分けることが実用的な運用のコツです。

pre-commitフック(ローカル)の役割: ・コミット前の速攻フィードバック(5秒以内を目標)
・セキュリティリスクの高い変更のブロック
・コミットメッセージの品質向上

CI/CD(GitHub Actions・GitLab CI等)の役割: ・全テスト・静的解析・型チェックの実行
・70Bクラスの大型モデルによる網羅的レビュー
・プルリクエスト単位でのまとめレビュー

pre-commitフックにLlama3.3:70b-instruct-q4_0のような大型モデルを使うとレスポンスに30秒以上かかり、コミットのたびに待たされます。ローカルフックはPhi-4かMistral:7b-instruct-q4_0の高速モデルに絞り、本格的なAIレビューはCI側に回すのが現実的です。

CI側でOllamaを使う場合は、チームのOllamaサーバーに接続するか、CI環境にOllamaをdocker runで立ち上げる方法があります。CI環境でのOllama活用については引き続きこのクラスターで解説予定です。

トラブルシューティングと注意点

**フックが実行されない**
最も多い原因は実行権限の欠落です。`ls -la .git/hooks/pre-commit` で `-rwxr-xr-x` になっているか確認します。`-rw-r--r--` だと実行されません。

# 権限確認 $ ls -la .git/hooks/pre-commit -rw-r--r-- 1 user user 1234 Sep 6 10:00 .git/hooks/pre-commit # ← 実行不可 # 修正 $ chmod +x .git/hooks/pre-commit $ ls -la .git/hooks/pre-commit -rwxr-xr-x 1 user user 1234 Sep 6 10:00 .git/hooks/pre-commit # ← OK

**Ollamaに接続できない**
`curl http://localhost:11434/api/tags` で直接確認します。`systemctl status ollama` でサービス状態も見てください。サービスがないなら `ollama serve &` で手動起動してください。

**差分が大きすぎてタイムアウトする**
`head -n 200` で行数を制限するか、対象ファイルの拡張子を絞ります(大量のデータファイルや設定ファイルの変更を除外)。Ollama APIの `num_ctx` パラメータを増やす方法もありますが、VRAMが必要です。大量のdiffはCI側に任せるのが適切な分担です。

**偽陽性が多い(問題ないコードがブロックされる)**
プロンプトの「BLOCK条件」を具体的にするほど精度が上がります。「コーディングスタイルの問題でBLOCKしない」「変数名の命名規則でBLOCKしない」と明示的に除外条件を書くと大幅に改善します。

**--no-verifyの多用防止**
`git commit --no-verify` は全フックをスキップします。乱用されると意味がなくなるため、チームのルールとして「使用時はSlackで報告」「週次でno-verify使用回数を集計」などの運用を決めておくと良いでしょう。

まとめ

OllamaをGitのpre-commitフックに組み込む手順を解説しました。シェルスクリプト1本とOllamaのREST APIだけで、機密コードを外部に送らないローカルLLMコードレビューが実現できます。
フック種別 主なコマンド・ファイル 効果
pre-commit git diff --cached | curl http://localhost:11434/api/generate 問題コードのコミットブロック
prepare-commit-msg .git/hooks/prepare-commit-msg コミットメッセージの自動下書き生成
チーム展開 pre-commit install + .pre-commit-config.yaml リポジトリ管理でチーム全員に配布
推奨モデル(高速) phi4 / mistral:7b-instruct-q4_0 ローカルフック向け(5秒以内を目標)
緊急スキップ git commit --no-verify 全フックをバイパス(運用ルール要)
まずはPhi-4を `ollama pull phi4` で取得し、`.git/hooks/pre-commit` に20行のスクリプトを置くだけで試せます。大規模な環境への展開前に個人リポジトリで動作を確認しておくのをおすすめします。

ローカルLLMによる開発自動化を2日間のハンズオンで体験する

pre-commitフックの設定からOllama API活用・RAGパイプライン構築まで、実際のGPU環境で手を動かしながら習得したい方向けに、「ローカルAIマスターセミナー」を開催しています。
少人数(最大8名)ZOOMハンズオン形式で実施しています。

>> ローカルAIマスターセミナーの詳細を確認する
ローカルLLMの構築・運用に関する関連記事もあわせて参考にしてください。

Ubuntu ServerでローカルLLMを構築する方法|Ollamaで機密データを外に出さず業務AIを動かす完全ガイド
社内でChatGPTが使えないときの代替手段|機密データを守るローカルLLMという選択肢
ローカルLLMのモデルを比較する方法|Llama3.3・Mistral・Gemma・Phi-4をUbuntuで使い分けるポイント

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。