セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
- 2.50.1 変更なし
-
2.50.0
2025-06-16
- 2.44.1 → 2.49.1 変更なし
-
2.44.0
2024-02-23
- 2.43.3 → 2.43.7 変更なし
-
2.43.2
2024-02-13
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.42.1 → 2.42.4 変更なし
-
2.42.0
2023-08-21
- 2.29.1 → 2.41.3 変更なし
-
2.29.0
2020-10-19
- 2.25.1 → 2.28.1 変更なし
-
2.25.0
2020-01-13
- 2.18.1 → 2.24.4 変更なし
-
2.18.0
2018-06-21
- 2.17.0 → 2.17.6 変更なし
-
2.16.6
2019-12-06
- 2.14.6 → 2.15.4 変更なし
-
2.13.7
2018-05-22
- 2.12.5 変更なし
-
2.11.4
2017-09-22
- 2.10.5 変更なし
-
2.9.5
2017-07-30
- 2.8.6 変更なし
-
2.7.6
2017-07-30
-
2.6.7
2017-05-05
- 2.2.3 → 2.5.6 変更なし
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
説明
このコマンドは様々なサブコマンドを取り、サブコマンドによって異なるオプションを使用します。
git bisect start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>] [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...] git bisect (bad|new|<term-new>) [<rev>] git bisect (good|old|<term-old>) [<rev>...] git bisect terms [--term-(good|old) | --term-(bad|new)] git bisect skip [(<rev>|<range>)...] git bisect reset [<commit>] git bisect (visualize|view) git bisect replay <logfile> git bisect log git bisect run <cmd> [<arg>...] git bisect help
このコマンドは二分探索アルゴリズムを使用して、プロジェクトの履歴の中でどのコミットがバグを導入したかを見つけます。まず、バグを含んでいると分かっている「悪い」コミットと、バグが導入される前だと分かっている「良い」コミットを指定します。次にgit
bisect
はこれら2つの端点の間にあるコミットを選び、選択されたコミットが「良い」か「悪い」かを尋ねます。変更を導入した正確なコミットが見つかるまで、範囲を絞り込み続けます。
実際、git
bisect
はプロジェクトの任意のプロパティを変更したコミットを見つけるために使用できます。例えば、バグを修正したコミット、またはベンチマークのパフォーマンスを向上させたコミットなどです。このより一般的な使い方をサポートするために、「良い」と「悪い」の代わりに「古い」と「新しい」という用語を使用したり、独自の用語を選択したりできます。詳細については、以下の「代替用語」セクションを参照してください。
基本的な二分探索コマンド: start, bad, good
例として、プロジェクトのバージョンv2.6.13-rc2
で機能していたはずの機能が壊れたコミットを見つけようとしているとします。以下のように二分探索セッションを開始します。
$ git bisect start $ git bisect bad # Current version is bad $ git bisect good v2.6.13-rc2 # v2.6.13-rc2 is known to be good
少なくとも1つの悪いコミットと1つの良いコミットを指定すると、git
bisect
はその履歴範囲の中間のコミットを選択し、それをチェックアウトして、次のような出力を表示します。
Bisecting: 675 revisions left to test after this (roughly 10 steps)
これで、チェックアウトされたバージョンをコンパイルしてテストする必要があります。そのバージョンが正しく動作する場合は、次のように入力します。
$ git bisect good
そのバージョンが壊れている場合は、次のように入力します。
$ git bisect bad
するとgit
bisect
は次のように応答します。
Bisecting: 337 revisions left to test after this (roughly 9 steps)
このプロセスを繰り返します。ツリーをコンパイルし、テストし、それが良いか悪いかに応じてgit
bisect
good
またはgit
bisect
bad
を実行して、次にテストする必要があるコミットを尋ねます。
最終的に検査するリビジョンがなくなると、コマンドは最初の悪いコミットの説明を出力します。refs/bisect/bad
という参照は、そのコミットを指したままになります。
二分探索のリセット
二分探索セッションの後、二分探索の状態をクリーンアップし、元のHEADに戻すには、以下のコマンドを発行します。
$ git bisect reset
デフォルトでは、これによりツリーはgit
bisect
start
の前にチェックアウトされていたコミットに戻ります。(新しいgit
bisect
start
も、古い二分探索の状態をクリーンアップするため、同様の動作をします。)
オプションの引数を指定すると、代わりに別のコミットに戻ることができます。
$ git bisect reset <commit>
例えば、git
bisect
reset
bisect/bad
は最初の悪いリビジョンをチェックアウトしますが、git
bisect
reset
HEAD
は現在の二分探索コミットに留まり、コミットの切り替えを一切行いません。
代替用語
バグを導入したコミットを探しているのではなく、何らかの「古い」状態と「新しい」状態の間で変更を引き起こしたコミットを探している場合があります。例えば、特定の修正を導入したコミットを探しているかもしれません。あるいは、ソースコードのファイル名がすべて会社の命名標準に変換された最初のコミットを探しているかもしれません。その他、何でも構いません。
そのような場合、「変更前の状態」と「変更後の状態」を指すのに「良い」と「悪い」という用語を使うと非常に混乱することがあります。そこで、代わりに「良い」と「悪い」の代わりにそれぞれ「古い」と「新しい」という用語を使うことができます。(ただし、1つのセッション内で「良い」と「悪い」を「古い」と「新しい」と混ぜることはできません。)
このより一般的な使い方では、何らかのプロパティを持つ「新しい」コミットと、そのプロパティを持たない「古い」コミットをgit
bisect
に提供します。git
bisect
がコミットをチェックアウトするたびに、そのコミットがそのプロパティを持っているかどうかをテストします。持っている場合は、そのコミットを「新しい」とマークします。持っていない場合は、「古い」とマークします。二分探索が完了すると、git
bisect
はどのコミットがそのプロパティを導入したかを報告します。
「良い」と「悪い」の代わりに「古い」と「新しい」を使用するには、引数なしでgit
bisect
start
を実行し、次に以下のコマンドを実行してコミットを追加する必要があります。
git bisect old [<rev>]
探し求める変更の前だったコミットを示すため、あるいは
git bisect new [<rev>...]
変更の後だったコミットを示すため。
現在使用されている用語のリマインダーを得るには、
git bisect terms
git
bisect
terms
--term-old
またはgit
bisect
terms
--term-good
で古い用語のみを取得できます。git
bisect
terms
--term-new
とgit
bisect
terms
--term-bad
は、探し求める変更よりも新しいコミットをどのように呼ぶかを学習するために使用できます。
「bad」/「good」や「new」/「old」の代わりに独自の用語を使用したい場合は、reset
、start
などの既存のbisectサブコマンド以外の好きな名前を選択して、以下のように二分探索を開始できます。
git bisect start --term-old <term-old> --term-new <term-new>
例えば、パフォーマンス低下を導入したコミットを探している場合、次のように使用できます。
git bisect start --term-old fast --term-new slow
あるいは、バグを修正したコミットを探している場合、次のように使用できます。
git bisect start --term-new fixed --term-old broken
次に、コミットをマークするには、git
bisect
good
とgit
bisect
bad
の代わりにgit
bisect
<term-old>とgit
bisect
<term-new>を使用します。
二分探索の視覚化/表示
二分探索プロセス中にgitkで現在残っている容疑者を見るには、以下のコマンドを発行します(サブコマンドview
はvisualize
の代替として使用できます)。
$ git bisect visualize
Gitは、X Window System環境のUnixシステムで設定されるDISPLAY
、インタラクティブデスクトップセッションでCygwinで設定されるSESSIONNAME
、Msys2およびGit for Windowsで設定されるMSYSTEM
、macOSのインタラクティブデスクトップセッションで設定される可能性のあるSECURITYSESSIONID
など、様々な環境変数を通じてグラフィカル環境を検出します。
これらの環境変数のいずれも設定されていない場合、代わりにgit logが使用されます。また、-p
や--stat
などのコマンドラインオプションを指定することもできます。
$ git bisect visualize --stat
二分探索ログと二分探索リプレイ
リビジョンを「良い」または「悪い」とマークした後、これまでに何が行われたかを表示するには、以下のコマンドを発行します。
$ git bisect log
リビジョンの状態の指定に誤りがあったことが判明した場合、このコマンドの出力をファイルに保存し、不正確なエントリを削除して編集し、以下のコマンドを発行して修正された状態に戻すことができます。
$ git bisect reset $ git bisect replay that-file
コミットのテストを避ける
二分探索セッションの途中で、提案されたリビジョンがテストに適していないとわかっている場合(例えば、ビルドに失敗し、その失敗が追跡しているバグとは関係ないことがわかっている場合)、代わりに近くのコミットを手動で選択してテストすることができます。
例
$ git bisect good/bad # previous round was good or bad. Bisecting: 337 revisions left to test after this (roughly 9 steps) $ git bisect visualize # oops, that is uninteresting. $ git reset --hard HEAD~3 # try 3 revisions before what # was suggested
次に、選択したリビジョンをコンパイルしてテストし、その後、通常の方法でそのリビジョンを「良い」または「悪い」とマークします。
二分探索のスキップ
自分で近くのコミットを選択する代わりに、以下のコマンドを発行してGitにそれを実行させることもできます。
$ git bisect skip # Current version cannot be tested
ただし、探しているコミットに隣接するコミットをスキップした場合、Gitはそれらのコミットのうちどれが最初の悪いコミットであったかを正確に特定することができません。
また、単一のコミットだけでなく、範囲表記を使用してコミットの範囲をスキップすることもできます。例えば、
$ git bisect skip v2.5..v2.6
これは、v2.5
以降のコミットのうち、v2.6
を含むコミットはテストすべきではないことを二分探索プロセスに伝えます。
範囲の最初のコミットもスキップしたい場合は、次のコマンドを発行することに注意してください。
$ git bisect skip v2.5 v2.5..v2.6
これは、v2.5
とv2.6
の間のコミット (両端を含む) はスキップすべきであることを二分探索プロセスに伝えます。
bisect startにさらにパラメータを与えて二分探索を短縮する
追跡している問題にどのツリーの一部が関係しているかが分かっている場合、bisect
start
コマンドを発行する際にパススペックパラメータを指定することで、試行回数をさらに減らすことができます。
$ git bisect start -- arch/i386 include/asm-i386
複数の良いコミットを事前に知っている場合、bisect
start
コマンドを発行する際に悪いコミットの直後にすべての良いコミットを指定することで、二分探索空間を絞り込むことができます。
$ git bisect start v2.6.20-rc6 v2.6.20-rc4 v2.6.20-rc1 -- # v2.6.20-rc6 is bad # v2.6.20-rc4 and v2.6.20-rc1 are good
二分探索の実行
現在のソースコードが良いか悪いかを判断できるスクリプトがある場合、以下のコマンドを発行して二分探索を実行できます。
$ git bisect run my_script arguments
上記の例のスクリプト(my_script
)は、現在のソースコードが良い/古い場合は終了コード0で終了し、現在のソースコードが悪い/新しい場合は125を除く1から127(両端を含む)のコードで終了する必要があることに注意してください。
その他の終了コードは、二分探索プロセスを中止します。exit
(-1
)で終了するプログラムは、$?=255になります(exit(3)マニュアルページ参照)。値は& 0377で切り捨てられるためです。
特別な終了コード125は、現在のソースコードをテストできない場合に使用されます。スクリプトがこのコードで終了した場合、現在のリビジョンはスキップされます(上記のgit
bisect
skip
を参照)。125は、この目的のために使用する最高の実用的な値として選ばれました。なぜなら、126と127はPOSIXシェルによって特定のエラー状態を通知するために使用されるためです(127はコマンドが見つからない場合、126はコマンドは見つかったが実行できない場合です。これらは、bisect
run
の観点からは、スクリプトにおける通常のエラーであるため、これらの詳細は重要ではありません)。
二分探索セッション中に、一時的な変更(例:ヘッダーファイルでs/#define DEBUG 0/#define DEBUG 1/、または「このコミットを持たないリビジョンには、この二分探索が関心のない別の問題を回避するためにこのパッチを適用する必要がある」)をテスト中のリビジョンに適用したいと часто思うことがあります。
このような状況に対処するため、内部のgit bisectが次にテストするリビジョンを見つけた後、スクリプトはコンパイル前にパッチを適用し、実際のテストを実行し、その後、リビジョン(必要に応じてパッチを適用したもの)がテストに合格したかどうかを判断し、ツリーを元の状態に戻すことができます。最後に、スクリプトは実際のテストのステータスで終了し、git
bisect
run
コマンドループが二分探索セッションの最終結果を決定できるようにする必要があります。
オプション
- --no-checkout
-
二分探索プロセスの各イテレーションで新しい作業ツリーをチェックアウトしません。代わりに、
BISECT_HEAD
という名前の参照を更新して、テストすべきコミットを指すようにします。このオプションは、各ステップで実行するテストがチェックアウトされたツリーを必要としない場合に役立つことがあります。
リポジトリがベアの場合、
--no-checkout
が想定されます。 - --first-parent
-
マージコミットに遭遇した場合、最初の親コミットのみを追跡します。
ブランチのマージによって導入された退行を検出する場合、マージコミットがバグの導入として識別され、その祖先は無視されます。
このオプションは、マージされたブランチに壊れたコミットやビルド不能なコミットが含まれていたが、マージ自体は問題なかった場合に、誤検出を避けるのに特に役立ちます。
例
-
v1.2とHEADの間で壊れたビルドを自動的に二分探索する
$ git bisect start HEAD v1.2 -- # HEAD is bad, v1.2 is good $ git bisect run make # "make" builds the app $ git bisect reset # quit the bisect session
-
originとHEADの間でテストの失敗を自動的に二分探索する
$ git bisect start HEAD origin -- # HEAD is bad, origin is good $ git bisect run make test # "make test" builds and tests $ git bisect reset # quit the bisect session
-
壊れたテストケースを自動的に二分探索する
$ cat ~/test.sh #!/bin/sh make || exit 125 # this skips broken builds ~/check_test_case.sh # does the test case pass? $ git bisect start HEAD HEAD~10 -- # culprit is among the last 10 $ git bisect run ~/test.sh $ git bisect reset # quit the bisect session
ここではカスタムスクリプト
test.sh
を使用します。このスクリプトでは、make
が失敗した場合、現在のコミットをスキップします。check_test_case.sh
は、テストケースがパスした場合はexit
0
、そうでない場合はexit
1
で終了する必要があります。test.sh
とcheck_test_case.sh
の両方がリポジトリの外にある方が、bisect、make、テストプロセスとスクリプトとの間の相互作用を防ぐために安全です。 -
一時的な変更 (ホットフィックス) を使用して自動的に二分探索する
$ cat ~/test.sh #!/bin/sh # tweak the working tree by merging the hot-fix branch # and then attempt a build if git merge --no-commit --no-ff hot-fix && make then # run project specific test and report its status ~/check_test_case.sh status=$? else # tell the caller this is untestable status=125 fi # undo the tweak to allow clean flipping to the next commit git reset --hard # return control exit $status
これは、各テスト実行の前にホットフィックスブランチからの変更を適用します。例えば、ビルドまたはテスト環境が変更され、古いリビジョンでは新しいリビジョンがすでに持っている修正が必要な場合などです。(マージが多すぎないように、ホットフィックスブランチが二分探索中のすべてのリビジョンに含まれるコミットに基づいていることを確認するか、
git
merge
の代わりにgit
cherry-pick
を使用してください。) -
壊れたテストケースを自動的に二分探索する
$ git bisect start HEAD HEAD~10 -- # culprit is among the last 10 $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh" $ git bisect reset # quit the bisect session
これは、テストを一行で記述すれば、実行スクリプトがなくても済むことを示しています。
-
破損したリポジトリでオブジェクトグラフの良い領域を見つける
$ git bisect start HEAD <known-good-commit> [ <boundary-commit> ... ] --no-checkout $ git bisect run sh -c ' GOOD=$(git for-each-ref "--format=%(objectname)" refs/bisect/good-*) && git rev-list --objects BISECT_HEAD --not $GOOD >tmp.$$ && git pack-objects --stdout >/dev/null <tmp.$$ rc=$? rm -f tmp.$$ test $rc = 0' $ git bisect reset # quit the bisect session
この場合、git bisect runが終了すると、bisect/badは、git pack objectsが要求する意味で、到達可能なグラフが完全に辿れる少なくとも1つの親を持つコミットを参照します。
-
コードの退行ではなく、修正を探す
$ git bisect start $ git bisect new HEAD # current commit is marked as new $ git bisect old HEAD~10 # the tenth commit from now is marked as old
または
$ git bisect start --term-old broken --term-new fixed $ git bisect fixed $ git bisect broken HEAD~10
GIT
git[1]スイートの一部