【Git】git bisect でバグ発生箇所を特定する方法を初心者向けにわかりやすく解説

Web開発

はじめに

Gitを使って開発を進めると、あるタイミングでプログラムが急にエラーを起こすことがあります。
問題の原因となったコミットを地道に探すのは大変だと感じる方もいるのではないでしょうか。

そんなときにgit bisectというコマンドを使うと、バグを引き起こしたコミットを少ない手間で特定しやすくなります。
初心者にも使いやすい機能で、実務現場でもよく活用されています。

本記事では、git bisectをどのように使えばバグ特定が簡単になるのか、その基本を解説していきます。
実務での使用シーンにも触れながら、手順や使いどころをわかりやすくまとめますので、興味がある方はぜひ最後までご覧ください。

この記事を読むとわかること

  • git bisectの概要と基本的な流れ
  • バグ発生箇所を探す手順やメリット
  • 実務でどのように活用できるか
  • 効率的にバグ特定を行うための注意点

git bisectとは

git bisectは、特定のバグを仕込んだコミットを二分探索で絞り込むための機能です。
「このコミット以降でバグが発生している」「このコミット以前はバグが発生していない」といった状態を繰り返し記録しながらコミット履歴を自動的に絞り込むことで、原因のコミットを短時間で見つけることができます。

一般的に開発していると、あるコミットまではプログラムが正常に動いていたのに、あるコミットから突然エラーが発生する状況が起こることがあります。
そのエラーの元になった変更点を人間の目で一つひとつ見ていくのは地味な作業になりがちです。
git bisectを使うことで、手動での検証回数をかなり減らすことができます。

git bisectの基本的な流れ

git bisectは以下のように二つの「境界」を設定してスタートします。

  1. バグが発生しているコミット(bad)
  2. バグが発生していないコミット(good)

そこからGitがコミットの真ん中あたりをチェックアウトしてくれるので、「ここではバグが起きるか、起きないか」を確認します。
確認後、「bad」か「good」かを再度指示すると、また次の中間コミットに移動してくれます。
それを繰り返して最終的に問題のコミットを特定します。

git bisectを使うメリット

バグ特定の時間短縮

大量のコミットがある場合、順番にチェックするのは大変です。二分探索の仕組みでチェック対象がどんどん半分に絞られるため、効率的に探せます。

手戻りを防ぎやすい

手動でコミットをどんどん遡る方法だと、どこを確認したか管理するのが面倒です。git bisectなら手順通りに進めれば見落としが減り、バグ原因の特定を確実に行えます。

初心者にも比較的やさしい

難しい手順を覚える必要はあまりありません。badとgoodを設定して結果を報告していくだけなので、初めて使う方でも理解しやすいです。

git bisectを使う実務での活用シーン

git bisectは、特に以下のようなシチュエーションでよく使われます。

大規模プロジェクトでの活用

チームで開発しているとコミットの数が膨大になり、どこにバグを仕込んだか追いかけきれなくなるケースがあります。
その際、手作業で調べると時間がかかってしまい、品質も下がりがちです。
git bisectを活用すると、改修履歴を自動的に分割しながら、怪しいコミットを正確に絞り込みます。

チームでのバグ修正

共同作業でコードを書いていると、誰かが行った変更が別の人のコードに影響を与えることがあります。
問題の原因が自分の手元にあるか、他のメンバーのコミットにあるか不明なときも、git bisectで洗い出すとトラブルの元を見つけやすくなります。

不具合の報告があったら、まず「どのコミットでバグが入ったか」を把握するのが最初の一歩です。

git bisectの具体的な手順

ここでは、実際のコマンド例を示しながら、基本的な使い方を説明します。
以下の流れはあくまで一例ですが、実務でもよく利用されるスタイルです。

git bisectの開始

まず、git bisectを開始するには以下のコマンドを実行します。

git bisect start

これを入力すると、二分探索モードがスタートします。
この状態で「どのコミットからバグが出ているか(bad)」「どのコミットまでは正常だったか(good)」を設定します。

badコミットとgoodコミットの指定

バグが確認できる最新コミットを bad として指定します。
通常は HEAD がもっとも新しいコミットなので、以下のように入力します。

git bisect bad HEAD

次に、バグがまだ存在しなかったことを確認できるコミットを good として設定します。
具体的にはバグが起きていなかった時点のコミットIDを指定します。

git bisect good <コミットID>

この操作を行うと、Gitが二分探索用にコミットの途中を自動的にチェックアウトします。
あとは、そのチェックアウトされた状態でプログラムを動かしてみて、バグが再現するかどうかを確認します。

バグの有無を報告して範囲を狭める

チェックアウトされたコミットでバグを再現できた場合は、以下のコマンドで「bad」と報告します。

git bisect bad

逆に、バグが再現しない場合は次のように「good」と報告します。

git bisect good

すると、Gitがさらにコミットの途中地点をチェックアウトしてくれます。
再度、バグが発生するかをテストして結果を報告…という流れを繰り返すことで、バグを仕込んだコミットが特定されるまで範囲を絞り込んでいきます。

git bisectの終了

問題となるコミットが特定できると、Gitがメッセージを表示し、そのコミットがバグの原因であることを教えてくれます。
二分探索が終わったら以下のコマンドでbisectモードを終了し、元のブランチ状態に戻しましょう。

git bisect reset

以上の流れを踏めば、手探りでコミットを調べるよりもはるかに速くバグの原因を見つけられます。

git bisect runで自動化を行う

少し発展的な使い方として、git bisect run コマンドがあります。
これはテストスクリプトなどを自動的に実行し、その結果に応じてgoodbadを自動で振り分ける方法です。

具体的には下記のように、テストを行うスクリプトやコマンドを指定します。

git bisect start
git bisect bad HEAD
git bisect good <コミットID>
git bisect run ./test_script.sh

上記の場合、./test_script.sh が0以外の終了コードを返せば「bad」、0を返せば「good」と判定されます。
大きなプロジェクトなどで自動テストを整備している場合は、このやり方でさらに効率よくコミットを特定できます。

テストスクリプトが誤った結果を返すと、bisectの判断も狂ってしまいます。スクリプトが正しく動いているかどうか確認してから利用しましょう。

バグ特定を効率化するポイント

実際にgit bisectを活用する際、スムーズにバグを見つけるためにはいくつか気をつける点があります。

コミットメッセージやログを把握する

コミットメッセージを読むだけで大まかな原因に当たりをつけられることも少なくありません。
bisectを回す前にコミット履歴をざっと確認し、どのあたりが怪しいか目星をつけると効率的です。
ただし、メッセージだけで絞り込めない場合はbisectを使うのが確実だと言えます。

小まめなコミットを心がける

複数の変更が混在するコミットばかりだと、どのコードがバグを生んだのかを突き止めるのが大変です。
小まめにコミットする習慣があると、bisectでも範囲が狭まりやすく、修正すべき箇所をすぐ見つけられます。

テスト環境を統一する

メンバーごとに環境がまったく違うと、誰かの手元ではバグが再現して、他の人の環境では再現しないケースがあります。
この場合、git bisectを行っても正しく判断できず、バグを見落とすリスクが出てきます。
チーム全員が同じテスト環境やフレームワークを使うことが望ましいでしょう。

まとめ

git bisectは、コミットを二分探索でどんどん絞り込んでいく便利な機能です。
バグが起きる境目を効率的に探し出すことができるため、開発現場では重宝されています。

開発規模が大きいほど、どこでバグが入ったのかを探るのは面倒になりがちです。
git bisectを使えば、手作業でのチェックが減り、原因コミットを見逃す可能性も下がります。
ぜひ活用して、バグ修正の効率を高めてみてください。

Gitをマスターしよう

この記事で学んだGitの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。