バグの原因コミットを探す- git bisect
バグを導入したコミットを二分探索(バイセクト)で特定します。
概念図
構文
git bisect <subcommand>使用例
バイセクトを開始
git bisect start現在のコミットをバグありとマーク
git bisect bad指定コミットをバグなしとマーク
git bisect good <commit>bisect の流れ(具体例)
100コミットの中からバグを探す場合、毎回中間のコミットをテストするため、わずか7回前後のテストで原因コミットを特定できます。
1000コミットでも約10回です。
bisect を開始して範囲を指定
git bisect start→git bisect bad(現在のHEADにバグあり)→git bisect good v1.0.0(v1.0.0 では動いていた)と宣言します。Git が中間コミットをチェックアウトする
自動的に範囲の真ん中のコミットに切り替わるので、テストを実行して挙動を確認します。
結果を報告する
バグがなければ
git bisect good、バグがあればgit bisect badを実行します。これを繰り返すと Git が二分探索で範囲を半分ずつ絞り込みます。原因コミットが特定されたら reset
最終的に原因となったコミットが表示されたら、
git bisect resetで元のブランチに戻ります。
# 手動でバグの原因コミットを探す基本的な流れ
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 扱いになります。
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 resetbisect が完了したら必ず
git bisect resetで元のブランチに戻りましょう。忘れると detached HEAD のまま作業して事故りがちです。
