症状

「以前は動いていた機能がいつの間にか壊れている。どのコミットでバグが入ったかわからない」

結論:まずこれを確認

  1. git bisect start で二分探索を開始する
  2. 正常なコミットを git bisect good、バグのあるコミットを git bisect bad で指定する
  3. 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
  

関連するトラブル

準備中

解決しない場合