[解決済み] git bisect の使用方法について教えてください。
質問
いくつかの記事で、次のように書かれています。
git bisect
はすごい。しかし、私はネイティブスピーカーではないので、なぜすごいのか理解できません。
どなたかサンプルコードで実演していただけませんか?
- どのように使用するのですか?
-
と同じようなものでしょうか?
svn blame
?
解決方法は?
の背後にある考え
git bisect
は、特定のリグレッションを見つけるために履歴のバイナリ検索を実行することです。次のような開発履歴があるとします。
... --- 0 --- 1 --- 2 --- 3 --- 4* --- 5 --- current
でプログラムが正常に動作していないことがわかります。
current
リビジョンで動作していたものが、リビジョン
0
. したがって、このリグレッションはおそらく次のいずれかのコミットで発生したものと思われます。
1
,
2
,
3
,
4
,
5
,
current
.
各コミットをチェックアウトし、ビルドし、リグレッションが存在するかどうかをチェックすることを試してみてはいかがでしょうか。コミット数が多い場合、これには長い時間がかかることがあります。これは線形探索です。バイナリサーチをすれば、もっとうまくいきます。これは
git bisect
コマンドで行います。各ステップで、悪いと思われるリビジョンの数を半分に減らそうとします。
コマンドはこんな風に使うんだ。
$ git stash save
$ git bisect start
$ git bisect bad
$ git bisect good 0
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[< ... sha ... >] 3
このコマンドの後に
git
はコミットをチェックアウトします。私たちの場合、それはコミット
3
. プログラムをビルドし、リグレッションが存在するかどうかを確認する必要があります。また
git
のどちらかでこのリビジョンのステータスを表示します。
git bisect bad
リグレッションが存在する場合、または
git bisect good
を指定します。
リグレッションがコミットで導入されたとします。
4
. では、このリビジョンにはリグレッションが存在しないので、それを伝えると
git
.
$ make
$ make test
... ... ...
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[< ... sha ... >] 5
その後、別のコミットをチェックアウトします。どちらかというと
4
または
5
(コミットが2つしかないため)。仮に
5
. ビルドの後、プログラムをテストして、リグレッションがあることを確認します。そして、次のように指示します。
git
:
$ make
$ make test
... ... ...
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[< ... sha ... >] 4
最後のリビジョンをテストします。
4
. そして、それはリグレッションを導入したものであるため、次のように指示します。
git
:
$ make
$ make test
... ... ...
$ git bisect bad
< ... sha ... > is the first bad commit
< ... commit message ... >
この単純な状況では、3つのバージョンをテストするだけでした(
3
,
4
,
5
)ではなく、4つ(
1
,
2
,
3
,
4
). これは小さな勝利ですが、これは私たちの履歴がとても小さいからです。検索範囲が N 個のコミットである場合、1 + log2 N 個のコミットに対して
git bisect
線形探索ではおよそN / 2コミットですが。
リグレッションが発生したコミットが見つかったら、そのコミットを調査して問題を見つけます。これが完了したら
git bisect reset
を使って、すべてを元の状態に戻してから
git bisect
コマンドを使用します。
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] Gitブランチをローカルやリモートで削除するには?
-
[解決済み] git pull」と「git fetch」の違いは何ですか?
-
[解決済み] コミット前に 'git add' を取り消すにはどうすればよいですか?
-
[解決済み] リモートのGitブランチをチェックアウトするには?
-
[解決済み] Git リポジトリを以前のコミットに戻すにはどうすればよいですか?
-
[解決済み] 現在のGit作業ツリーからローカル(未追跡)ファイルを削除する方法
-
[解決済み] Git で、ステージされていない変更を破棄するにはどうしたらいいですか?
-
[解決済み】"git pull" でローカルファイルを強制的に上書きするには?
-
[解決済み】ローカルのGitブランチの名前を変更するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] あなたのブランチは 'origin/master' より 3 コミット進んでいます。
-
[解決済み】GitHubで空のブランチを作成する
-
[解決済み】Githubエンタープライズ - リモート。Git の操作でパスワード認証が利用できない
-
[gitコミット失敗の解決] 現在のブランチの先端が後ろにあるため、更新が拒否されました。
-
Gitのプッシュでエラーが発生! [リモート拒否] master -> master (pre-receive hook declined) error: failed to push some refs to .......
-
gitコミット発生 ! [リモート拒否] master -> master (pre-receive hook declined) 解決策
-
git commit リモートエラー [rejected] master -> master (フェッチファースト)
-
[解決済み] git でディレクトリ階層が異なる 2 つのブランチをマージするには?
-
[解決済み] GitBash | origin master - rejected (fetch first) | GitHub リポジトリにファイルがない。
-
[解決済み] GitのFETCH_HEADとはどういう意味ですか?