開発をしているといつの間にかバグが混入することがありますよね。混入タイミングが分からない場合はとりあえず正しく動く時期のコミットを見つけて、バグが発生するまで地道に調べていくと思います。
そんなときに使えるコマンドが git bisect です。
git bisect はコミットログからバグが発生したコミットを見つける手助けをしてくれます。
git-scm.com
今回の検証に使ったgit version は 2.26.2 です。
サンプルコード
検証用にバグが混入しているリポジトリを用意しました。最新のコミットはテストコードが通りません。
github.com
基本的な使い方
バグが混入しているコミットと正しく動いていたコミット間から混入したコミットを見つけます。正しく動いていたコミットは確実に動いていた時期のコミットを指定します(1週間前は確実に動いていたのになーって感じならその時期のコミットを指定します)。この2つのコミット間を二分探索で絞り込みながら見つけていきます。
1.調査開始
git bisect start
コマンドを使って調査を開始します。開始時にバグが混入しているコミットと正しく動いていたコミットを指定します。
以下のコマンドではgit bisect bad
で最新のコミットにバグが混入していることを指定し、git bisect good HEAD~8
で8個前のコミットでは確実に動いていたことを指定しています。
git bisect start git bisect bad git bisect good HEAD~8
また、以下のように書いても同じ意味です。
git bisect start HEAD HEAD~8
2.調査
「1.調査を開始する」を実行した後のworking treeは二分探索で絞り込まれたコミットの環境になっています。この環境で動作確認をして正しく動作すればgit bisect good
、正しく動作しなければgit bisect bad
を入力します。入力後のworking treeは二分探索で絞り込まれた新たなコミットの環境になっています。
これを繰り返すと<コミットID> is the first bad commit
のメッセージが出て初めてバグが混入したコミットを見つけられます。
3.調査完了
git bisect reset
でgit bisect start
前のコミットに戻れます。
テストコードがあれば自動探索できる
バグかどうかを発見できるテストコードなどがあれば、git bisect run
コマンドで自動探索できます。
*1
たとえば以下のようにgit bisect run
コマンドの引数でdotnetのテストを実行すると自動で判断しながら特定のコミットを発見してれます。
git bisect start HEAD HEAD~8 git bisect run "C:\Program Files\dotnet\dotnet.exe" test
TortoiseGitでbisect
TortoiseGitでもgit bisect
が使えます。基本はCUIと同じで、操作がGUIになるだけです。
1.調査開始
右クリックのメニューからBisect startを選択します。
バグが混入しているコミットと正しく動いていたコミットを選択します
goodは「...」から正しく動いていた頃のログを選択します。
2.調査
working treeは二分探索で絞り込まれたコミットの環境になっているので動作確認をしてBisect good、Bisect badを選択していきます。
これを繰り返すと<コミットID> is the first bad commit
のメッセージが出て初めてバグが混入したコミットを見つけられます。
3.調査完了
Bisect resetでBisect start前のコミットに戻れます。
まとめ
二分探索でバグが混入したコミットを見つけてくれるgit bisect
コマンドを調べました。どのタイミングで混入したか分からないバグを探すときには便利なコマンドです。
*1:そもそも、テストコードがあればbisectコマンドが必要になる前にバグ混入に気づけると思いますが