Git: git bisect で「どのコミットで壊れたか」を二分探索する
「前は動いていたのに今は壊れている」とき、git bisect は良い/悪いを答えるだけで原因のコミットを二分探索で特定する。確かめ方をコマンドにできれば git bisect run で全自動。
使う場面
- 回帰バグの原因コミットが分からず、間のコミットが数十〜数百あるとき(1000 コミットでも 10 回程度の判定で済む)
- 性能劣化やテスト失敗が「いつから」起きたか調べたいとき
やり方
sh
# 悪いコミット(今)と良いコミット(動いていた頃)を指定して開始
git bisect start HEAD v1.4.0
# Git がチェックアウトした中間コミットを試し、結果を答える
git bisect good # このコミットは正常
git bisect bad # このコミットは壊れている
git bisect skip # ビルドできない等で判定できない
# 最初の悪いコミットが表示されたら終了して元のブランチに戻る
git bisect reset自動化:
sh
git bisect start HEAD v1.4.0
git bisect run npm test -- tests/login.test.ts
# 終了コード 0 = good、1〜127(125 以外)= bad、125 = skip
git bisect reset注意点
runに渡すスクリプトは「そのコミット時点のファイル」で動く。テスト自体が後から追加されたものなら、リポジトリ外(例:/tmp/check.sh)に置いて実行する。- 依存のインストールが必要な場合はスクリプトの中で
npm ciなどを行う(時間はかかる)。 - マージコミットが多い履歴では
git bisect start --first-parentで本流のコミットだけを辿ると分かりやすい。 - 途中経過は
git bisect log、やり直しはgit bisect replay。 - 「どのコミットで文字列が入ったか」なら Git: git log -S で「この文字列を足した/消したコミット」を探す のほうが速い。