セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
ガイド
- gitattributes
- コマンドラインインターフェースの規約
- 日々のGit
- よくある質問 (FAQ)
- 用語集
- フック
- gitignore
- gitmodules
- リビジョン
- サブモジュール
- チュートリアル
- ワークフロー
- すべてのガイド...
管理
低レベルコマンド
- 2.44.1 → 2.47.0 変更なし
-
2.44.0
02/23/24
- 2.43.3 → 2.43.5 変更なし
-
2.43.2
02/13/24
-
2.43.1
02/09/24
-
2.43.0
11/20/23
- 2.42.1 → 2.42.3 変更なし
-
2.42.0
08/21/23
- 2.29.1 → 2.41.2 変更なし
-
2.29.0
10/19/20
- 2.25.1 → 2.28.1 変更なし
-
2.25.0
01/13/20
- 2.18.1 → 2.24.4 変更なし
-
2.18.0
06/21/18
- 2.17.0 → 2.17.6 変更なし
-
2.16.6
12/06/19
- 2.14.6 → 2.15.4 変更なし
-
2.13.7
05/22/18
- 2.12.5 変更なし
-
2.11.4
09/22/17
- 2.10.5 変更なし
-
2.9.5
07/30/17
- 2.8.6 変更なし
-
2.7.6
07/30/17
-
2.6.7
05/05/17
- 2.2.3 → 2.5.6 変更なし
-
2.1.4
12/17/14
-
2.0.5
12/17/14
説明
このコマンドは、様々なサブコマンドと、サブコマンドに応じた異なるオプションを取ります。
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
は、プロジェクトの**あらゆる**プロパティを変更したコミットを見つけるために使用できます。例えば、バグを修正したコミットや、ベンチマークのパフォーマンスを向上させたコミットなどです。このより一般的な使用方法をサポートするために、「良い」と「悪い」の代わりに「古い」と「新しい」という用語を使用することも、独自の用語を選択することもできます。詳細については、以下の「代替用語」セクションを参照してください。
基本的なbisectコマンド: start, bad, good
例として、プロジェクトのバージョン v2.6.13-rc2
で動作していたことがわかっている機能を壊したコミットを見つけようとしているとします。bisectセッションは次のように開始します。
$ 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
は、そのコミットを指したままになります。
Bisect reset
bisectセッションの後、二分探索の状態をクリーンアップし、元の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
を使用すると、目的の変更よりも新しいコミットの呼び方を学ぶことができます。
「悪い」/「良い」または「新しい」/「古い」の代わりに独自の用語を使用したい場合は、二分探索を開始することで、好きな名前(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>
を使用します。
Bisect visualize/view
現在残っている容疑者を *gitk* で表示するには、二分探索プロセス中に次のコマンドを実行します(サブコマンド `view` は `visualize` の代わりに使用できます)。
$ git bisect visualize
Gitは、さまざまな環境変数を通じてグラフィカル環境を検出します。UnixシステムのX Window System環境で設定される `DISPLAY`。対話型デスクトップセッションでCygwinで設定される `SESSIONNAME`。Msys2とGit for Windowsで設定される `MSYSTEM`。対話型デスクトップセッションでmacOSで設定される `SECURITYSESSIONID`。
これらの環境変数がどれも設定されていない場合、代わりに *git log* が使用されます。`-p` や `--stat` などのコマンドラインオプションも指定できます。
$ git bisect visualize --stat
Bisect log と bisect replay
リビジョンを良いまたは悪いとマークした後、次のコマンドを実行して、これまでに何が行われたかを表示します。
$ git bisect log
リビジョンのステータスを指定する際に間違いを犯したことが判明した場合は、このコマンドの出力をファイルに保存し、編集して間違ったエントリを削除してから、次のコマンドを実行して修正された状態に戻すことができます。
$ git bisect reset $ git bisect replay that-file
コミットのテストの回避
bisectセッションの途中で、推奨されたリビジョンがテストに適していないことがわかっている場合(たとえば、ビルドに失敗し、その失敗が追跡しているバグと関係がないことがわかっている場合)、近くのコミットを手動で選択して、代わりにそれをテストできます。
例えば
$ 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
次に、選択したリビジョンをコンパイルしてテストし、その後、通常どおりリビジョンを良いまたは悪いとマークします。
Bisect skip
近くのコミットを自分で選択する代わりに、次のコマンドを実行してGitにそれを実行するように依頼できます。
$ git bisect skip # Current version cannot be tested
ただし、探しているコミットに隣接するコミットをスキップすると、Gitはそれらのコミットのどちらが最初の悪いコミットであったかを正確に判断できません。
1つのコミットだけでなく、範囲表記を使用してコミットの範囲をスキップすることもできます。例えば
$ git bisect skip v2.5..v2.6
これは、`v2.5` 以降、`v2.6` までのコミットをテストすべきではないことをbisectプロセスに指示します。
範囲の最初のコミットもスキップしたい場合は、次のコマンドを実行することに注意してください。
$ git bisect skip v2.5 v2.5..v2.6
これは、bisect プロセスに対して、v2.5
と v2.6
の間のコミット(両端を含む)をスキップする必要があることを指示します。
bisect start により多くのパラメータを与えることでbisectを絞り込む
bisect start
コマンドを実行する際に pathspec パラメータを指定することで、追跡している問題にツリーのどの部分が関係しているかを知っている場合、試行回数をさらに減らすことができます。
$ git bisect start -- arch/i386 include/asm-i386
事前に複数の正常なコミットがわかっている場合は、bisect start
コマンドを実行する際に、不良なコミットの直後にすべての正常なコミットを指定することで、bisect の範囲を絞り込むことができます。
$ 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
bisect run
現在のソースコードが正常か不良かを判断できるスクリプトがある場合は、次のコマンドを実行することで bisect を行うことができます。
$ git bisect run my_script arguments
スクリプト(上記の例では my_script
)は、現在のソースコードが正常/古い場合はコード 0 で終了し、現在のソースコードが不良/新しい場合は 1 から 127(両端を含む)の間のコード(ただし 125 を除く)で終了する必要があることに注意してください。
その他の終了コードは bisect プロセスを中止させます。 exit(-1)
を介して終了するプログラムは、値が & 0377
で切り捨てられるため、$? = 255 を残します(exit(3) マニュアルページを参照)。
特別な終了コード 125 は、現在のソースコードをテストできない場合に使用してください。スクリプトがこのコードで終了すると、現在のリビジョンはスキップされます(上記の git bisect skip
を参照)。125 は、この目的で使用できる最も意味のある値として選択されました。126 と 127 は POSIX シェルによって特定のエラー状態を通知するために使用されるためです(127 はコマンドが見つからない場合、126 はコマンドが見つかったが実行できない場合です。これらの詳細は、bisect run
に関してはスクリプトの通常のエラーであるため、重要ではありません)。
bisect セッション中に、テストされているリビジョンに一時的な変更(例:ヘッダーファイルの s/#define DEBUG 0/#define DEBUG 1/、または「このコミットがないリビジョンには、この bisect が関心のない別の問題を回避するためにこのパッチを適用する必要がある」)を適用したいことがよくあります。
このような状況に対処するために、内部の _git bisect_ がテストする次のリビジョンを見つけた後、スクリプトはコンパイル前にパッチを適用し、実際のテストを実行し、その後、リビジョン(必要なパッチが適用されている可能性がある)がテストに合格したかどうかを判断してから、ツリーを元の状態に戻すことができます。最後に、スクリプトは実際のテストのステータスで終了し、git bisect run
コマンドループが bisect セッションの最終的な結果を決定できるようにする必要があります。
オプション
- --no-checkout
-
bisect プロセスの各反復で新しい作業ツリーをチェックアウトしないでください。代わりに、
BISECT_HEAD
という名前の参照を更新して、テストするコミットを指すようにします。このオプションは、各ステップで実行するテストでチェックアウトされたツリーが必要ない場合に役立ちます。
リポジトリが bare の場合、
--no-checkout
が想定されます。 - --first-parent
-
マージコミットを見つけた場合は、最初の親コミットのみをたどります。
ブランチのマージによって導入されたリグレッションを検出する際に、マージコミットはバグの導入として識別され、その祖先は無視されます。
このオプションは、マージされたブランチに壊れたコミットまたはビルドできないコミットが含まれていたが、マージ自体は問題なかった場合に、誤検知を回避するのに特に役立ちます。
例
-
v1.2 と HEAD の間の壊れたビルドを自動的に bisect する
$ 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 の間のテストの失敗を自動的に bisect する
$ 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
-
壊れたテストケースを自動的に bisect する
$ 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
する必要があります。bisect、make、およびテストプロセスとスクリプト間の相互作用を防ぐため、
test.sh
とcheck_test_case.sh
の両方がリポジトリ外にある方が安全です。 -
一時的な変更(ホットフィックス)を使用して自動的に bisect する
$ 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
これは、各テスト実行の前にホットフィックスブランチからの変更を適用します。たとえば、ビルド環境またはテスト環境が変更されたため、古いリビジョンに新しいリビジョンに既に存在する修正が必要になる場合があります。(ホットフィックスブランチが、bisect しているすべてのリビジョンに含まれているコミットに基づいていることを確認して、マージが多すぎないようにするか、
git merge
の代わりにgit cherry-pick
を使用してください。) -
壊れたテストケースを自動的に bisect する
$ 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
これは、テストを 1 行で記述すれば、実行スクリプトなしで実行できることを示しています。
-
破損したリポジトリ内のオブジェクトグラフの正常な領域を見つける
$ 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] スイートの一部