4

Git リポジトリで何かが失敗していることに突然気付いたとします。しかし、数コミット前に機能していたことは知っていますが、どのコミットかは覚えていません。git bisect を実行するために「適切な」コミットを見つけようとする代わりに、Git に (おそらく bash スクリプトを使用して) 尋ねたいのですが、最新の「適切な」コミットは何ですか?

少し前のコミットを選択してそれを良いものとして使用しないもう 1 つの理由は、私のレポには多くの悪いコミットと良いコミットが混在しているためです。直線的ではありません。

では、最新のコミットから始めて必要なだけループし、悪い場合は 1 を返し、良い場合は 0 を返すコマンドを実行するにはどうすればよいでしょうか?

4

1 に答える 1

7
while ! good-or-bad-test-command ; do
   git checkout HEAD^
done

ただし、破損がどこかの最後の数コミット内にある場合は、これを手動で行うことができます。

$ good-or-bad-test-command
# if it fails, then:
$ git checkout HEAD^ # pop to previous
$ good-or-bad-test-command # <-- recalled by hitting up arrow in bash
# still fails:
$ git checkout HEAD^ # <-- recalled with up arrow
$ good-or-bad-test-command # <-- recalled
...

履歴のリコールのおかげで、ループを叩くよりも少ないキーストロークで済みます。

git checkoutブランチHEADの移動を回避し、 で簡単に回復できる「切り離された状態」にしますgit checkout <yourbranch>

[編集、2017 年 3 月]

しかし、問題は、なぜgit bisectこの状況でまだ使用するのでしょうか? 悪いコミットから良いコミットまで直線的に検索しました。同じ情報に対して別の二分探索を行う必要はありません。

まだ良いコミットを見つけるために推測して、始める方が手順が少ないかもしれませんgit bisect

最近何かを壊した疑いがある場合は、16 件のコミットをさかのぼってください。または32または何でも。最後にタグ付けされたリリースに戻ります。二分探索はすぐにゼロになります:

$ git bisect start
$ git bisect bad # HEAD known to bad; almost always the case
$ git checkout HEAD~8  # wild guess; almost certainly before breakage
$ good-or-bad-test-command # check: is it really good?
$ # if not, git checkout HEAD~8 # go back more, repeat test
$ git bisect good  # bisect begins

非常に長い歴史を持つ git があり、何かがずっと前に壊れていたこと (以前はテストされていなかったものが現在テストされている) を発見した場合、指数関数的に逆方向にプローブして適切なコミットを見つけることができますgit checkout HEAD~16。それが良くない場合は、git checkout HEAD~32; それからgit checkout HEAD~64

これは、未知の範囲でのバイナリ検索の一般的な戦略です。アルゴリズムを線形にするため、範囲を決定するために線形にスキャンしないでください。範囲を指数関数的に拡張すると、対数のままになります。

于 2014-05-25T13:06:49.393 に答える