
「昨日までは確かに動いていた機能が、今日動かなくなっている」
「どのコミットでバグが入り込んだのか見当がつかない」
開発現場でよくあるこの状況。手当たり次第にチェックアウトして確認するのは時間がかかりすぎます。そんな時に最強の武器となるのが、**二分探索(バイナリサーチ)**で犯人を特定する git bisect コマンドです。
今回は、「DM(チャット)機能が動かなくなった」という具体的なケースを例に、バグの原因となったコミットを特定する手順を解説します。
1. 状況の整理
まず、現状を整理します。
- 症状: DM(チャット)画面でメッセージ送信や表示が正常に動作しない。
- 現在の状態 (Bad): 最新のコミット(HEAD)では確実に壊れている。
- 過去の状態 (Good): 「あの機能を追加する前」や「あのブランチを切った直後」は確実に動いていた。
この「壊れている地点」と「動いていた地点」の間にあるコミットを、Gitが自動的に半分ずつ絞り込んでくれます。
2. git bisect の開始手順
PowerShell(またはターミナル)を開き、以下の手順で進めます。
Step 1: bisect モードを開始し、現状を「Bad」とする
まず、「今から犯人探しを始めます」と宣言し、現在の壊れている最新コミット(ここでは例として bad1234 とします)を「Bad」に指定します。
PowerShell
# bisectの開始
git bisect start
# 現在のコミット(HEAD)はバグがあるので bad
git bisect bad bad1234
# ※ HEADの場合は単に git bisect bad でもOK
Step 2: 確実に動いていた過去を「Good」とする
次に、探索の終端となる「正常だったコミット」を指定します。ここが重要なポイントです。
「どのコミットをGoodにするか?」は、**「確実に動いていた記憶がある一番近い場所」**を選ぶのがセオリーです。
例えば、debug-test-branch ブランチを作成した直後は動いていたと仮定しましょう。その時点のコミットID(例: good567)を指定します。
PowerShell
# 「この時は動いていた」というコミットIDを指定
git bisect good good567
このコマンドを打った瞬間、Gitは以下のようなメッセージを出し、「Bad」と「Good」のちょうど中間のコミットに自動的にチェックアウトします。
Plaintext
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[test001] Refactor: optimize database query for chat logs
3. 犯人の絞り込み(テストの実施)
Gitが中間のコミット(上記例では test001)に移動してくれたので、その状態で実際に動作確認を行います。
- サーバーを起動:docker-compose up web など、環境に合わせたコマンドを実行。
- 動作テスト:ブラウザでチャット画面を開き、「送信 → リロード」を行ってDMが正しく表示されるか確認します。
テスト結果に応じたコマンド入力
検証結果に合わせて、以下のどちらかを入力します。
- DMが正常に動いた場合PowerShell
git bisect good→ 「ここは無罪(シロ)」と判断され、Gitは**より新しい(未来側の)**中間コミットへ移動します。 - DMが壊れていた場合PowerShell
git bisect bad→ 「ここも有罪(クロ)」と判断され、Gitは**より古い(過去側の)**中間コミットへ移動します。
これを数回繰り返すと、対象範囲がどんどん半分になり、最終的にGitが以下のように「真犯人」を教えてくれます。
Plaintext
buggy99 is the first bad commit
commit buggy99...
Author: Jun Oogawara <jun@example.com>
Date: Wed Nov 19 14:30:00 2025 +0900
Fix: Merge pull request #42 from feature/example-new-function
これで犯人が特定できました!
この例では、buggy99(マージコミット)でバグが混入したことがわかります。
4. 終了処理
犯人がわかったら、最後に以下のコマンドで元の最新の状態(HEAD)に戻ります。
PowerShell
git bisect reset
まとめ
git bisect を使えば、「いつ壊れたかわからない」という絶望的な状況でも、機械的にバグ混入コミットを特定できます。
git bisect startgit bisect bad(今)git bisect good good567(過去)- テストして
goodかbadを繰り返す - 特定完了(
buggy99 is the first bad commit) git bisect resetで終了
「どのコード変更がきっかけだったか」を特定してから修正に取り掛かることで、解決までの時間を大幅に短縮しましょう。
