Git Ready
バグの原因コミットを探す - git bisect の使い方・オプション・サンプル

バグの原因コミットを探す- git bisect

バグを導入したコミットを二分探索(バイセクト)で特定します。

概念図

git bisect diagram

構文

bash
git bisect <subcommand>

使用例

バイセクトを開始

bash
git bisect start

現在のコミットをバグありとマーク

bash
git bisect bad

指定コミットをバグなしとマーク

bash
git bisect good <commit>

bisect の流れ(具体例)

100コミットの中からバグを探す場合、毎回中間のコミットをテストするため、わずか7回前後のテストで原因コミットを特定できます。

1000コミットでも約10回です。

  1. bisect を開始して範囲を指定

    git bisect startgit bisect bad(現在のHEADにバグあり)→ git bisect good v1.0.0(v1.0.0 では動いていた)と宣言します。

  2. Git が中間コミットをチェックアウトする

    自動的に範囲の真ん中のコミットに切り替わるので、テストを実行して挙動を確認します。

  3. 結果を報告する

    バグがなければ git bisect good、バグがあれば git bisect bad を実行します。これを繰り返すと Git が二分探索で範囲を半分ずつ絞り込みます。

  4. 原因コミットが特定されたら reset

    最終的に原因となったコミットが表示されたら、git bisect reset で元のブランチに戻ります。

bash
# 手動でバグの原因コミットを探す基本的な流れ
git bisect start
git bisect bad                   # 現在のHEADにバグがある
git bisect good v1.0.0           # v1.0.0ではバグがなかった

# 中間コミットをテストした結果を報告
git bisect good                  # バグなし → さらに先へ
git bisect bad                   # バグあり → もっと前へ

# 終了して元に戻る
git bisect reset

自動化:git bisect run

テストスクリプトが用意できている場合、git bisect run で全工程を自動化できます。

  • テストの終了コードで判定

    終了コード 0 は good、1-124 および 126-127 は bad、125 は skip として扱われます。npm test のような既存のテストコマンドをそのまま渡せば動きます。

  • ビルドできないコミットはスキップ

    ビルドできないコミットがある場合は git bisect skip でスキップできます。カスタムスクリプトからは終了コード 125 を返すと skip 扱いになります。

bash
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run npm test          # テストが失敗=bad、成功=good と判定

注意点

  • bisect 中は detached HEAD 状態

    git bisect 中は detached HEAD 状態になるため、この状態でコミットを作成しないよう注意してください。

  • 終わったら必ず git bisect reset

    bisect が完了したら必ず git bisect reset で元のブランチに戻りましょう。忘れると detached HEAD のまま作業して事故りがちです。

関連コマンド