libgit2 ヘッダーでは、フェッチ後、分析中に早送りが使用可能であることが通知された場合、必要なのはフェッチされたヒントの単純なチェックアウト (およびヘッド/<ブランチ> の変更) であると読みました。論理的に思えましたが、 refs/heads/<branch> を remotes/<remote>/<branch> とどのように区別できるのでしょうか? コミットには親が埋め込まれています。これは単一の履歴を構成しますが、2 つの履歴が必要で、両方に追加の「マージ」コミットがあります。では、早送りはどのように実装されますか? 実際には両方の履歴でSHAハッシュが繰り返されることにつながるため、libgit2にはその意味があるようです。
2 に答える
「早送り」はマージではありません。ブランチ ポインタをマージの「自分の」側に設定するだけです。
いくつかの歴史を考えてみましょう:
1 -- 2 -- 3 -- 4 -- 5 -- 6
そして、私のmaster
ブランチはコミット 4 にあり、サーバーのmaster
ブランチはコミット 6 にあると考えてください。
親のマスター ブランチを自分のブランチに (おそらくプルの一部として) マージしたい場合、マージの最初のステップは、マージ ベース、またはこれら 2 つのコミット間の共通の祖先を見つけることです。
この場合 (上記)、4は4 と 6 の間の共通の祖先です。したがって、サーバーが持っていないローカルのコミットはありません。そのため、ブランチを単純に「早送り」して、ポインターを 6 を指すように更新することができます。これを行うことでデータが失われることはありません (ただし、何も作成されません。「早送りなし」オプションを使用して実際のマージを強制した場合は、4 と 6 の間に新しいマージ コミットを作成します。
git_merge_analysis
そのため、マージを早送りできるかどうかを識別するlibgit2 の関数は、文字通り、「yours」ブランチが「irs」ブランチとの共通の祖先であるかどうかを確認するだけです。
もちろん、これは典型的なマージのケースではありません。検討:
F -- G
/
A -- B -- C -- D -- E
この場合、あなたがG
ローカルにコミットしていて、アップストリームがコミットしている場合、E
あなたの共通の祖先はC
あり、早送りは不可能です。真のマージを実行する必要があります。