症状
「以前は動いていた機能がいつの間にか壊れている。どのコミットでバグが入ったかわからない」
結論:まずこれを確認
git bisect startで二分探索を開始する- 正常なコミットを
git bisect good、バグのあるコミットをgit bisect badで指定する - Git が自動でコミットを絞り込み、原因コミットを特定する
操作フロー
flowchart TD
A[バグを発見] --> B[正常だったコミットを特定]
B --> C[git bisect start]
C --> D[git bisect bad で現在のコミットをマーク]
D --> E[git bisect good で正常コミットをマーク]
E --> F{Gitが中間コミットをチェックアウト}
F --> G[動作確認]
G --> H{バグあり?}
H -->|Yes| I[git bisect bad]
H -->|No| J[git bisect good]
I --> F
J --> F
F --> K[原因コミットを特定]
K --> L[git bisect reset で終了]
よくある原因
- コミット数が多すぎて手動確認が困難 - 数十〜数百コミットの中から原因を探す必要がある
- いつからバグがあるか不明 - 明確な「正常だった時点」を思い出せない
- 複数人での開発で変更が追えない - 他のメンバーの変更が原因の可能性がある
- テストがなく自動検出できない - 手動確認に頼るしかない
- リリース後に発覚したバグ - 本番環境で初めて気づいた問題
- マージコミットが多い - 履歴が複雑で追跡が難しい
操作手順
ステップ1: 現在の状態を確認する
git status
git log --oneline -20
🔍 チェックポイント: 作業中の変更がないこと。未コミットの変更があると bisect 中に失われる可能性がある
ステップ2: 正常だったコミットを特定する
過去のコミットやタグで、バグがなかったことが確実なポイントを見つける。
# 過去のタグ一覧を確認
git tag
# 特定のコミットに移動して動作確認
git checkout <commit-hash>
# 動作確認後、元のブランチに戻る
git checkout -
🔍 チェックポイント: 「このコミットでは確実に動いていた」という基準点を見つける
ステップ3: bisect を開始する
git bisect start
🔍 チェックポイント: Waiting for both good and bad commits... と表示される
ステップ4: バグがあるコミットをマークする
現在の HEAD(バグがある状態)を bad としてマークする。
git bisect bad
または特定のコミットを指定する場合:
git bisect bad <commit-hash>
ステップ5: 正常なコミットをマークする
ステップ2で特定した正常なコミットを good としてマークする。
git bisect good <commit-hash>
🔍 チェックポイント: Bisecting: X revisions left to test after this と表示され、中間のコミットが自動でチェックアウトされる
ステップ6: 動作確認と判定を繰り返す
Git がチェックアウトしたコミットでバグの有無を確認する。
# バグがある場合
git bisect bad
# バグがない場合
git bisect good
# このコミットではテストできない場合(ビルドエラー等)
git bisect skip
🔍 チェックポイント: 二分探索なので、1000コミットあっても約10回の確認で原因を特定できる
ステップ7: 原因コミットの特定
探索が完了すると、以下のようなメッセージが表示される。
abc1234 is the first bad commit
commit abc1234
Author: example <example@example.com>
Date: Mon Jan 1 12:00:00 2026 +0900
Fix: some feature
ステップ8: bisect を終了する
git bisect reset
🔍 チェックポイント: 元のブランチ・コミットに戻っていること。git status で確認する
(応用)スクリプトで自動化する
テストスクリプトがある場合、自動で bisect を実行できる。
git bisect start
git bisect bad HEAD
git bisect good <good-commit>
git bisect run ./test-script.sh
スクリプトの終了コード:
0: good(正常)1-124, 126-127: bad(バグあり)125: skip(テスト不可)
NG行動
- 未コミットの変更がある状態で bisect を開始する - チェックアウト時に変更が失われる可能性がある
- good/bad を間違えてマークする - 誤った結果になる。
git bisect logで履歴を確認できる - bisect 中に他の作業をする - bisect を終了してから別作業を行う
- bisect reset を忘れる - detached HEAD 状態のままになる
よくある質問(FAQ)
Q1: good/bad を間違えてマークした場合はどうする?
A: git bisect reset で一度終了し、最初からやり直す。または git bisect log > bisect.log でログを保存し、修正後 git bisect replay bisect.log で途中から再開する。
Q2: 特定のコミットでビルドできない場合は?
A: git bisect skip でそのコミットをスキップする。ただし、スキップが多いと原因コミットを絞り込めない場合がある。
Q3: マージコミットはどう扱われる?
A: 通常のコミットと同様に扱われる。--first-parent オプションで主系列のみを対象にすることも可能。
git bisect start --first-parent
関連するトラブル
準備中
解決しない場合
- Git bisect 公式ドキュメント
git bisect logで bisect の履歴を確認する- 「git bisect 自動化」「git bisect スクリプト」で検索する