svnmerge は、特定のブランチからのいくつかの変更セットをブロックするのに役立ちます。これは Mercurial でどのように達成できますか?
1 に答える
サブバージョンがマージと呼ぶものは、Mercurial でのマージとはかなり異なります。svnmerge または実行する操作svn merge
は、通常、他のバージョン管理システムでは「チェリー ピック」と呼ばれます。基本的に、ターゲットブランチの元の変更セットのコピーである新しいコミットを作成します。Mercurial では、移植拡張機能を使用して実行できます。
この方法は、保守が難しい複数のヘッドを作成するため、通常のマージと比較して DVCS ではあまり一般的ではありません。これを使用する方法と、結果の出力は次のようになります。
$ hg checkout -r 8
$ hg branch release
$ hg transplant 10
applying 8ba2867cf974
8ba2867cf974 transplanted to 1f5920f61c94
7---8---9---A [default]
\
B [release]
ここに、トランクのバグを修正するコミット A があり、hg transplant
それをリリースして、A と同じ変更を含むが親が異なる新しいコミット B を作成します。
別のアプローチは、移植を使用せず、リリース ブランチへの修正のみをチェックインすることです。新しいリリース ブランチを作成してそこで修正を行い、リリース ブランチをデフォルトにマージします。それは次のようになります。
$ hg checkout -r 8
$ hg branch release
... fix fix fix ...
$ hg commit -m"Make fix A"
$ hg checkout -r 9
$ hg merge release
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m"Merged release branch"
7---8---9---B- [default]
\ /
A---- [release]
ここで B はマージコミットです。それに関連する「余分な」変更はなく (競合が解決された場合を除きます)、リリース ブランチをその時点でデフォルトにマージされたものとしてマークする特別なプロパティがあります。バグを修正する実際の変更セットは 1 つだけです - 「A」とマークされたもの - もちろん、変更自体はデフォルトのブランチにもあります。
このアプローチの利点は次のとおりです。
- 頭は一つだけ。これにより、開発者が混乱することが少なくなり、良い閉鎖感が得られます
- デフォルトには、リリースからのすべてのバグ修正が含まれていることが一目でわかります
- リリースには重要なバグ修正が含まれていることがわかります
通常、リリース ブランチ「v1.1」などの適切な場所にタグを付けて、そのリリースがどこから来たのかがわかるようにします。
このアプローチの欠点は次の場合です。
- リリースが古すぎるため、デフォルトにマージすると競合が発生します
- デフォルトにマージしたくないリリース時の変更と、必要な変更が混在している
最初の問題でできることはあまりありません。非常に古いブランチを維持しなければならない場合、いずれにせよブランチが分岐することになります。とにかく、パッチはおそらく非常に異なっています。
2 番目の問題は、たとえば、リリース バージョンに「緊急」パッチがあり、バグを修正または回避するが、根本的な問題に対処するためにデフォルトでより大きな修正が必要な場合に発生します。その場合、リリースをマージしてから、不要なコミットを「元に戻す」ために新しい明示的なコミットを作成する必要があります。
このプラクティスには、実際にはある意味で同様の利点がsvn merge
あります。変更をトランクからリリースに選択的にマージする場合、マージしたリビジョンを覚えておく必要があります (すべてのトランクをマージしないと仮定して)。svn merge
svn:mergeinfo プロパティを設定しますが、これらを追跡すると問題が発生する可能性があります。さらに、ログを注意深くチェックして、「ああ、ええ、その修正をリリースにマージしました」と言う必要があります。
修正があるときにリリース ブランチ全体をトランクに svn-merge する場合、どのリビジョンがマージされたかを覚えておく必要はありません。