以前は問題なく動いていたはずの機能が、最新版では動かなくなっている・・・。こんなときは、「どのコミットが問題を混入させてしまったのだろうか?」を知りたくなるでしょう。
これを手助けするのが git bisect コマンドです。git bisect コマンドは、二分探索によって問題箇所を特定します。
事前準備
最初に大事なことがひとつあります。それは、「問題がない(good)状態と問題がある(bad)状態を、確実に判定できるようにする」 ことです。
当然のことではありますが、ここがあやふやだと、二分探索をしても問題箇所をうまく特定できません。
可能なら、「テストスクリプトを1つ実行するだけで判定」できるようにしたほうが良いです。このとき、テストスクリプトは、git リポジトリからチェックアウトした作業ツリーに対して実行できるようにします(例えばソースからのビルド処理もテストスクリプトに含めます)。また、テストスクリプトは、good なら 0 を、bad なら 1~127(ただし 125 は除く)を返すようにします。
テストスクリプトが用意できない場合は、手動でテストを行うこともできます。
git bisect の実行方法
good と bad の指定
まず、問題がない(good)時点と問題がある(bad)時点を指定します。
$ git bisect start <bad-commit> <good-commit>
たとえば、V1.0 タグの時点では good で、最新(HEAD)では bad である、とすると次のように指定します。
$ git bisect start HEAD V1.0
これを実行すると、bad と good の間にある適当な中間バージョンがチェックアウトされます。
テストスクリプトの指定
次に、テストスクリプトを指定します(テストスクリプトが用意できない場合は、次の「手動でテストする」に進んでください)。
$ git bisect run <テストスクリプトのファイル名>
これを実行すると、git が自動的に「テスト実行」と「中間バージョンのチェックアウト」を繰り返して、問題が混入した時点を見つけてくれます。処理が終わるまで特にすることはありませんので、コーヒーでも飲んで心を落ち着けながら待ちましょう。
無事終了すれば、問題が混入した時点のバージョンがチェックアウトされています。コミット内容を調べて問題を解決しましょう。
手動でテストする
テストスクリプトが用意できない場合、手動でテストを行います。
テストの結果、問題がない(good)なら以下を実行します。
$ git bisect good
テストの結果、問題がある(bad)なら以下を実行します。
$ git bisect bad
上記のどちらかを実行すると、git が自動的に bad と good の間にある中間バージョンをチェックアウトしてくれます。これに対して、ふたたび手動でテストを行います。
手動の「テスト実行」と git による「中間バージョンのチェックアウト」を繰り返すと、問題が混入した時点が特定できます。コミット内容を調べて問題を解決しましょう。
その他のコマンド
現在チェックアウトしているコミットを確認する
git bisect がチェックアウトしているコミットを見るには、次のコマンドが便利です。
$ git bisect view
デフォルトだと gitk で表示します。オプション -p をつけると、パッチ形式でコンソールに出力します。
二分探索の過程を確認する
git bisect のログを表示します。
$ git bisect log
もとの状態に戻す
git bisect を実行する前の状態に戻すには、以下を実行します。
$ git bisect reset
まとめ
git bisect を使う機会はそんなに多くはないと思いますが、こういうものがあるということを覚えておくと、いざというときに助かります。実際に使ってみると、きっと感動しますよ。