開発ブランチのマージ問題

主系キャンディス のブランチでもっと いろいろな作業が起こったとしましょう。以下のようになりました:


      mainline-0.1                    candice-0.1
      ------------                    -----------
        base-0             -----------> base-0 (a tag)
        patch-1  ---------'             patch-1
        patch-2             ----------> patch-2
        patch-3  ----------'  --------' patch-3
        patch-4  <-----------'          patch-4
        patch-5
        patch-6


        % larch revisions --summary -A lord@emf.net--2003-candice \
                          hello-world--candice--0.1
        base-0
            tag of 
            lord@emf.net--2003-example/hello-world--mainline--0.1--patch-1
        patch-1
            Punctuated the output correctly
        patch-2
            merge from mainline sources
        patch-3
            added a period to output string
        patch-4
            capitalized the output string



        % larch revisions --summary -A lord@emf.net--2003-example \
                          hello-world--mainline--0.1
        base-0
            initial import
        patch-1
            Fix bugs in the "hello world" string
        patch-2
            commented return from main
        patch-3
            added copywrong statements
        patch-4
            merge from Candice's Branch
        patch-5
            fixed the copyrwrong for hw.c
        patch-6
            fixed the copyrwrong for main.c

私達の目標が、主系での新しい作業内容を、キャンディス のブランチにマージすることである、という状況を考えてみます。言い替えると 以下のようにしたいとします:


      mainline-0.1                    candice-0.1
      ------------                    -----------
        base-0             -----------> base-0 (a tag)
        patch-1  ---------'             patch-1
        patch-2             ----------> patch-2
        patch-3  ----------'  --------' patch-3
        patch-4  <-----------'          patch-4
        patch-5               --------> patch-5
        patch-6  ------------'

そのようなマージはどうやったらいいのでしょうか? 最後のマージ前のキャンディスのリビジョンから始めましょう (patch-4):


        % larch get -A lord@emf.net--2003-candice \
                       hello-world--candice--0.1--patch-4 \
                       hw-C-4
        [....]

        % cd hw-C-4

ここで、実際にはうまく動作しないふたつのやり方があります:

replay は、開発ブランチマージ問題を解決しません

replay主系にあるすべての『反映されていない』 変更をキャンディスのツリーにマージしようとします。適用する チェンジセットの一覧は、以下のようにして求めることができます:


        % larch whats-missing --summary \
                              -A lord@emf.net--2003-example \
                              hello-world--mainline--0.1
        patch-4
            merge from Candice's Branch
        patch-5
            fixed the copyrwrong for hw.c
        patch-6
            fixed the copyrwrong for main.c

この一覧中で問題になるのはpatch-4です。それは、 キャンディスのブランチから、patch-2の 段階までの全ての変更を含んでいます。しかしそのような変更はすでにキャンディス のブランチのpatch-4リビジョンに現れています — それで replay を適用すれば、冗長な部分が発生してしまいます(パッチが衝突してしまいます)

進んだユーザに対する注意: replay コマンドは、主系からpatch-4リビジョンを スキップすることを認めるようなオプションがあります。その手のこと は問題を解決しますが、欠点もあります。まずそれはキャンディスのブランチ のwhats-missingの出力に、patch-4が繰り返し現れる ことを意味します。つぎに、patch-4チェンジセットがキャンディス のブランチからのマージだけを含んでいるということを保証できません。 もしアリスとボブがpatch-4に別の変更を加えたのなら、そのチェンジセット をスキップするので、その部分の変更は失われてしまいます。

update は開発ブランチマージ問題を解決しません

主系のブランチからupdateしてみましょう。update は、プロジェクトツリーの一番若い主系の祖先から、ツリー自身までのチェンジセットを 計算し、それを最後の主系リビジョンに適用するものであることを思いだしください。

これを表現する記法を示します。 X から Y へのチェンジセットを以下のように書きます:

        delta(X, Y)

この場合 update主系 patch-3 のリビジョンから、私達のプロジェクトツリーまでのチェンジセットを計算することで 始まります。

        delta(mainline--0.1--patch-3, hw-C-4) 

XからYまでのチェンジセットを、ツリーZに 適用した結果のツリーは、以下のように書きます:

        delta(X, Y) [ Z ]

言い替えると、私達の例でのupdate の結果は、以下のように記述することが できます:

        delta(mainline--0.1--patch-3, hw-C-4) [mainline--0.1--patch-6]

しかし、問題があります。主系patch-3 リビジョン はキャンディスのブランチに前もってマージされていません。それで 以下のチェンジセット

        delta(mainline--0.1--patch-3, hw-C-4)

は、他の変更に混じって、キャンディスのブランチのpatch-1patch-2 の変更を含んでいます。

不幸にもそのチェンジセットを適用したツリー、 mainline––0.1––patch-6は、既にキャンディス ブランチの base-0...patch-2 とマージされてしまっています。

replayの場合と同様、update は、冗長な 変更をすることによってマージ衝突をおこすでしょう。