私はこの問題は、マージはあなたが思うよりも異なる動作をすることであると信じています。あなたは書きます
新しいリリースブランチには、すべての機能ブランチチェンジセットが含まれています(何もバックアウトされていない)ので、なぜデフォルトのブランチもこれらのチェンジセットをすべて受け取りませんか?
2つのブランチをマージすると、あるブランチから別のブランチにすべての変更を適用すると考えるのは間違いです。したがって、default
ブランチは、release2
からのチェンジセットを「受信」しません。これは私たちが通常マージを考える方法ですが、それは不正確です。
Mercurialは2つのチェンジのための共通の祖先を見つける:あなたは2つのチェンジをマージするとき、本当に何が起こる
は次のとおりです。
2つのチェンジセットで異なるファイルごとに、Mercurialは先祖ファイル、最初のチェンジセットのファイルと2番目のチェンジセットのファイルを使用してthree-way merge algorithmを実行します。あなたのケースでは
、リビジョン11と12をマージしている以上の共通の祖先が改訂8です。これは、Mercurialは、三方があるリビジョンからファイル間でマージを実行することを意味します:
リビジョン8:なしバックアウト
リビジョン11:機能ブランチがバックアウトされた
リビジョン12:3ウェイマージにノーバックアウト
、変更は常に変化がないことを切り札ません。 Mercurialは、ファイルが8から11の間で変更されたことを確認し、8から12の間で変更がないことを確認します。したがって、マージでリビジョン11の変更されたバージョンが使用されます。これは、任意の3方向マージアルゴリズムに適用されます。フルマージテーブルは次のようになりますどこold
、new
、... 3つのファイル内の一致ハンクの内容は次のとおりです。
ancestor local other -> merge
old old old old (nobody changed the hunk)
old old new new (they changed the hunk)
old new old new (you changed the hunk)
old new new new (hunk was cherry picked onto both branches)
old foo bar <!> (conflict, both changed hunk but differently)
私は怖いもので、すべての理由は、この驚くべきマージ動作のmerge changeset shouldn't be backed out。 Mercurial 2.0以降では、マージを取り消そうとすると中止して文句を言うでしょう。
一般に、3ウェイマージアルゴリズムでは、がすべて変更されているとみなすことができます。。したがって、branch1
をdev
にマージし、後でバックアウトでマージを元に戻すと、マージアルゴリズムは状態が以前よりも優れているとみなします。つまり、後でbranch1
をdev
に再度マージして、バックアウトされた変更を元に戻すことはできません。
default
にマージするときに「ダミーマージ」を使用することができます。あなたは、単にマージし、常にdefault
にあなたがマージしているリリースブランチから変更を保つ:ちょうどrelease2
ようになり、問題と力default
をサイドステップします
$ hg update default
$ hg merge release2 --tool internal:other -y
$ hg revert --all --rev release2
$ hg commit -m "Release 2 is the new default"
。これは、リリースブランチにマージされずにdefault
に全く変更が加えられていないことを前提としています。
スキップされた機能を備えたリリースを作成できる必要がある場合、「正しい」方法は、それらの機能をまったくマージしないことです。マージは強力なコミットメントです:あなたはMercurialに、マージチェンジセットは両方の祖先からのすべての良いものを持っていると伝えます。 Mercurialがあなたにpick your own base revision when mergingを渡さない限り、三方向マージアルゴリズムはあなたがバックアウトについてあなたの心を変えることを許さないでしょう。
ただし、できることは、バックアウトのバックアウトです。これは、フィーチャーブランチからリリースブランチに変更を再導入することを意味します。
release: ... o --- o --- m1 --- m2 --- b1
/ /
feature-A: ... o --- o /
/
feature-B: ... o --- o --- o
あなたは、あなたのリリースブランチに別の機能をマージ:
release: ... o --- o --- m1 --- m2 --- b1 --- m3
/ / /
feature-A: ... o --- o / /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
だからあなたはあなたが今機能が悪かったと判断し、マージをバックアウト
release: ... o --- o --- m1 --- m2
/ /
feature-A: ... o --- o /
/
feature-B: ... o --- o --- o
のようなグラフで始まります
今すぐA機能を再導入したい場合は、b1
を取り消すことができます。
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
/ / /
feature-A: ... o --- o / /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
私たちはより良い、いつどこで変更内容を表示するようにグラフにデルタを追加することができます。
+A +B -A +C --A
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
をこの第二のバックアウトした後、あなたは新しいチェンジセットが追加されている場合にはfeature-A
で再び合流することができます。グラフは次のようにルックスをマージしている:
release: ... o --- o --- m1 --- m2 --- b1 --- m3 --- b2
/ / /
feature-A: ... o -- a1 - a2/ /
/ /
feature-B: ... o --- o --- o /
/
feature-C: ... o --- o --- o --- o --- o
、あなたはa2
とb2
をマージします。共通の祖先はa1
になります。つまり、3方向マージで考慮する必要がある変更は、a1
とa2
とa1
とb2
の間の変更だけです。ここではb2
にはすでに "in"の変更内容が含まれていますa2
したがって、マージは小さくなります。
hg diff -r 9 -r 12 ??? –