最近、Mercurialでリリースブランチを保守するときに変更をスキップすることについていくつかの質問がありました。例えば:
2.0で導入されて以来、この問題を回避するためにgraft
を使用することを考えてきました。次のようなリビジョンツリーが与えられた場合:
A---B---C---D---E---F---G---H---I---J
邪悪な変更E
をスキップするリリースブランチを作成する必要があるとします。
hg update -r D
hg graft "F::J"
私たちに与えます:
A---B---C---D---E---F---G---H---I---J
\
--F'--G'--H'--I'--J'
transplant
はF::J
からパッチを生成し、それをD
に適用したことを理解できますが、graft
は3-wayマージを使用すると言われていますパッチではなく。だから.......それはどのように機能しますか?なぜそれが良いのですか?E
を修正し、それをリリースブランチにマージするとしましょう。
--E2-----------------
/ \
A---B---C---D---E---F---G---H---I---J---M1
\ \
--F'--G'--H'--I'--J'---------M2--
M1はストレートマージです。特別なものはありません。 M2は、「同じ」(または少なくとも同等の)変更が加えられたブランチをマージしています。
D
、J'
、およびM1
を使用した通常の3方向マージですか?そして最後に...
D
に更新してF::J
を移植すると、Mercurialは多くのマージを実行します。このマージから始まります:
M = three_way_merge(local=D, other=F, base=E)
状態C
とD
の間のデルタに+d
を書き込む場合、次から始めます。
+d +e +f
---- C ---- D ---- E ---- F ----
グラフを時計回りに90度回転すると、上記の3者間マージは次のようになります。
-e
.---- D
/
E
\
'---- F
+f
つまり、E
から始めてD
に到達するために-e
の反対を適用したと仮定します。 +e
の逆パッチと考えています。 E
から始めて、通常のデルタ+f
でF
状態にも行きました。ここには奇妙なことは何もありません—リポジトリにはすべての状態(D
、E
、およびF
)が既にあります。このように見えるので、D
とF
をマージできることは明らかです。
マージとは、「ダイヤモンドを完成させる」ことです。そのため、M
とD
が混在し、F
とD
の違いが+f
に似ている新しい状態M
が見つかります。 F
からM
までは、-e
に似ています。次のようになります。
-e +f'
.---- D ----.
/ \
E M
\ /
'---- F ----'
+f -e'
+f
デルタは+f'
になり、-e
デルタは-e'
になりました。これは通常の3者間マージですが、効果は興味深いです。F
の代わりにD
をE
に適用しました!
マージ後、M
からF
への2番目の親はドロップされます。
-e +f'
.---- D ----.
/ \
E M
\
'---- F
+f
繰り返しますが、F
の「効果」をD
にコピーしました。つまり、D
に適用されるデルタ(+f'
)が見つかり、+f
と同じ効果が得られました。 E
に適用されます。グラフを少しまっすぐにして、以下を取得できます。
+f'
--- D ---- M
\
'---- E ---- F
+e +f
その結果、F
が完全な3方向機構を使用してD
にグラフトされます。
Q1:ここで何が起きたのですか?だから.......それはどのように機能しますか?なぜそれが良いのですか?
A1:マージ機構は名前の変更などを考慮に入れるため、パッチを使用するよりもマージの方が優れています。
Q2:このマージは、D、J '、およびM1を使用した通常の3方向マージですか?
A2:はい、グラフはグラフのトポロジを変更しません。
Q3: Mercurialは、マージ操作に役立つグラフト操作に関する追加情報を保存/使用しましたか?
A3:いいえ.
Q4:このようなフローの潜在的な問題は何ですか?
A4:マージの観点からは問題なく動作するはずです。それは人々を混乱させるかもしれないいくつかの歴史を複製します。
Q1:競合がある場合に役立ちます。その後、通常のマージツールを使用できます(私にとっては、インライン競合マーカーです。これは、Emacsのsmergeモードで編集します)。
Q2:通常のマージです。
Q3:いいえ。
Q4:ほぼ同一のブランチが2つあるのは見苦しいと思います。