Git bisectとは?バグの原因コミットを二分探索で特定する方法を解説

Git bisectの使い方と実践的な活用方法を初心者向けに解説します。二分探索アルゴリズムを使ってバグを引き起こしたコミットを効率的に特定する方法を学びましょう。手動での実行から自動化まで詳しく説明します。

Git bisectとは

Git bisectは、バグを引き起こしたコミットを二分探索(バイナリサーチ)で効率的に特定するコマンドです。「以前は動いていたのに、いつの間にか動かなくなった」という問題の原因を見つけるときに非常に役立ちます。

たとえば、1000個のコミットがある中からバグの原因を探す場合、1つずつ確認すると最大1000回のチェックが必要です。しかしbisectを使えば、二分探索により約10回(log₂1000 ≒ 10)のチェックで原因を特定できます。

bisectの仕組み

bisectは「正常だったコミット」と「問題が発生しているコミット」の間を半分に分割しながら、問題の原因となったコミットを絞り込んでいきます。

上の図で、コミットAは正常(good)、コミットHで問題が発生(bad)している場合、bisectはまず中間のコミットDをチェックします。Dが正常ならD〜Hの間を、問題があればA〜Dの間を次に調べます。この繰り返しで原因を絞り込みます。

bisectの基本的な使い方

bisectセッションを開始する

まず、bisectセッションを開始します。

git bisect start

問題のあるコミットを指定する(bad)

現在のコミット(HEAD)で問題が発生している場合は、以下のように指定します。

# 現在のコミットを問題あり(bad)としてマーク
git bisect bad

特定のコミットを指定することもできます。

git bisect bad <コミットハッシュ>

正常だったコミットを指定する(good)

問題が発生していなかった(正常に動作していた)コミットを指定します。

git bisect good <コミットハッシュ>

goodとbadの両方を指定すると、Gitは自動的に中間のコミットをチェックアウトします。

Bisecting: 5 revisions left to test after this (roughly 3 steps)
[abc1234...] コミットメッセージ

各コミットを確認してマークする

チェックアウトされたコミットで問題があるかどうかを確認し、結果をマークします。

# 問題がある場合
git bisect bad

# 問題がない場合
git bisect good

このプロセスを繰り返すと、最終的に問題を引き起こした最初のコミットが特定されます。

abc1234... is the first bad commit
commit abc1234...
Author: 開発者名 <email@example.com>
Date:   Mon Jan 6 10:00:00 2026 +0900

    問題のある変更を追加

bisectセッションを終了する

原因が特定できたら、bisectセッションを終了して元のブランチに戻ります。

git bisect reset

実践的な使用例

具体的なワークフロー

実際のバグ調査の流れを見てみましょう。

# 1. bisectを開始
git bisect start

# 2. 現在のHEAD(main)で問題が発生している
git bisect bad

# 3. 1週間前のコミットでは正常だったことがわかっている
git bisect good abc1234

# 4. Gitが自動的に中間のコミットをチェックアウト
# Bisecting: 15 revisions left to test after this (roughly 4 steps)

# 5. アプリをビルドしてテスト
npm run build
npm test

# 6. テスト結果に応じてマーク
git bisect good  # または git bisect bad

# 7. 手順5-6を繰り返す

# 8. 原因が特定されたら終了
git bisect reset

skipを使う

特定のコミットがビルドできない、またはテストできない場合はskipでスキップできます。

git bisect skip

スキップされたコミットの前後から調査が続行されます。ただし、スキップが多いと原因の特定が困難になる場合があります。

bisectの自動化

手動で毎回テストするのは大変です。テストスクリプトを用意すれば、bisectを完全に自動化できます。

自動化の基本

git bisect runコマンドに、テスト用のスクリプトを渡します。スクリプトが終了コード0を返せばgood、0以外ならbadとして扱われます。

git bisect start HEAD abc1234
git bisect run <テストスクリプト>

テストスクリプトの例

Node.jsプロジェクトで特定のテストが通るかどうかを確認する場合:

#!/bin/bash
# test-bug.sh

# 依存関係をインストール
npm ci

# 特定のテストを実行
npm test -- --grep "問題のあるテスト"

# テスト結果の終了コードがそのまま返される

このスクリプトを実行可能にして、bisect runに渡します。

chmod +x test-bug.sh
git bisect start HEAD abc1234
git bisect run ./test-bug.sh

終了コードの意味

終了コード意味
0good(正常)
1〜124, 126, 127bad(問題あり)
125skip(スキップ)
128〜bisect中止

ビルドに失敗した場合にskipとしたい場合は、スクリプト内で終了コード125を返すようにします。

#!/bin/bash
# test-bug.sh

npm ci || exit 125  # ビルド失敗ならskip

npm test -- --grep "問題のあるテスト"

初心者が混乱しやすいポイント

bisect中に作業内容が変わることへの戸惑い

bisect中はGitが自動的にコミットをチェックアウトするため、作業ディレクトリの内容が次々と変わります。これは正常な動作であり、git bisect resetを実行すれば元の状態に戻れます。

bisectを始める前に、未コミットの変更がないことを確認しましょう。

# 変更がある場合はstashで退避
git stash
git bisect start
# ... bisect作業 ...
git bisect reset
git stash pop

goodとbadの指定を間違えた場合

goodとbadを逆に指定してしまった場合、bisectは正しく動作しません。途中で間違いに気づいたら、いったんリセットしてやり直すのが確実です。

git bisect reset
git bisect start
# 正しい順序で指定し直す

bisectとblameの使い分け

どちらも問題の原因を探すツールですが、用途が異なります。

ツール用途適したケース
bisectいつから問題が発生したかを特定動作の変化、回帰バグ
blame特定の行を誰がいつ変更したかを確認コードの意図を調べたい、特定行の変更履歴

「この機能が動かなくなった」→ bisect 「この行はなぜこう書かれているのか」→ blame

よくある問題と対処法

マージコミットがある場合

マージコミットが含まれる履歴でbisectを使う場合、--first-parentオプションでメインブランチのコミットのみを対象にできます。

git bisect start --first-parent

問題の再現が難しい場合

断続的にしか再現しない問題の場合、テストを複数回実行するスクリプトを作成します。

#!/bin/bash
# flaky-test.sh

for i in {1..5}; do
  npm test || exit 1
done

exit 0

途中経過を確認したい

bisectの進捗状況を確認するにはgit bisect logを使います。

git bisect log

出力例:

git bisect start
# bad: [hash1] 最新のコミット
git bisect bad hash1
# good: [hash2] 正常だったコミット
git bisect good hash2
# bad: [hash3] 中間コミット
git bisect bad hash3

このログを保存しておけば、後から同じ調査を再現できます。

git bisect log > bisect.log
git bisect reset

# 後から再現
git bisect replay bisect.log

bisectを活用するためのヒント

効果的にbisectを使うためのポイントをまとめます。

ポイント説明
こまめなコミットコミットが細かいほど原因の特定が容易
動作するコミット各コミットがビルド・テスト可能な状態を維持
自動テストの整備bisect runによる自動化が可能になる
タグの活用リリースポイントにタグを付けておくとgoodの指定が楽

特に「各コミットが動作する状態を維持する」ことは、bisectに限らずGitを使う上で重要な習慣です。中途半端な状態でコミットすると、bisect時にビルドエラーでスキップが多発し、調査が困難になります。

まとめ

Git bisectは、バグの原因コミットを二分探索で効率的に特定するツールです。

  • git bisect startでセッション開始
  • git bisect badで問題のあるコミットを指定
  • git bisect goodで正常なコミットを指定
  • 各コミットをテストしてgood/badをマーク
  • git bisect resetで終了

手動での確認が面倒な場合は、git bisect runでテストスクリプトを指定して自動化できます。

数百、数千のコミットがある大規模なプロジェクトでも、bisectを使えば数回のテストでバグの原因を特定できます。「以前は動いていたのに」という問題に遭遇したら、ぜひbisectを活用してみてください。

編集部

編集部