SOでgit mergeとgit rebaseに関連する質問を読みましたが、内部で何が起こっているのかまだ完全には理解できません。
分岐状況は次のとおりです。
MASTER------------------------
\ \
\ \----Feature B---
\ \
\-----Feature A----------\---Feature A+B
異なる時点でmasterから派生する2つの機能ブランチがあります。2つのブランチを結合したいと考えています。 first rebase then merge
練習しますが、機能Aを機能Bにリベースすると、競合が発生します。両方の機能(およびマスター)が同じ領域で変更されているため、これは予想されています。しかし、奇妙なことは、git rebase --continue
。これは私たちを夢中にさせるので、リベースを中止し、git merge
。競合は実際に簡単に解決できることがわかりました。
私の質問は2つあります。
git rebase
私たちの状況に適していますか?または、リベースは、わずかな(1または2)変更をプルするのに適していますか?rebase
は1つずつ競合を解決しますが、どのコミットを何と比較するのですか?SOに関連する投稿:
Feature A
およびFeature B
がsharedブランチであるという事実に基づいて、私は言うno 。
リベースはブランチをマージする方法で、マージコミットを持たずに(つまり、2つ以上の親を持つコミット)を線形履歴として表示します。local branchesのマージに最適です。これは、ローカルリポジトリにのみ存在し、他の人に公開されていないブランチです。どうして?少なくとも2つの理由のため:
リベースにより、コミットID(つまり、メタデータのSHA-1
ハッシュ)が変更されます。これは、リベースされたコミットをshared branchにプッシュすると、完全にnew commitsとして表示されることを意味しますたとえ同じ変更がまだ含まれている場合でも、ローカルリポジトリでそれらを取得する人。現在、誰かがその間に古いコミットの上に新しいコミットを追加した場合、彼らはそれらを移動する必要があります。これにより、不必要な混乱が生じます。
パブリックブランチをマージするとき、多くの場合、wantでそれらをmerge commitsにして、コミット方法を追跡できるようにします。ブランチ間を移動しました。その情報はリベースすると失われます。
ただの定期的なマージ。違いは、git rebase
が一度に1つのコミットをマージすることです共通の親から開始する前のコミットの上に。 git merge
は、2つのコミットとその変更セット全体を1つの操作としてマージするため、競合を1回解決するだけで済みます。
@Jubobsがコメントで指摘したように、Gitには、複数回発生する競合を解決するための自動化されたソリューションがあります: git rerere
、または "記録された解像度を再利用」。
マージの競合が発生するたびに、構成ファイル(rerere.enabled true
)でrerereを有効にすると、Gitは競合するファイルの状態を記録しますbeforeおよびafterをマージします。次回、同じ競合が発生します–マージの両側でexact same linesを含む競合– Gitは以前に記録した同じ解像度を自動的に適用します。また、マージ出力でそれについて通知します。
CONFLICT(コンテンツ): 'somefile'の競合のマージ
以前の解像度を使用して「somefile」を解決しました。
ここで、 詳細git rerere
を使用して競合を処理する方法を見つけることができます。