70

Mercurial/TortoiseHg で、次の例を考えると、リビジョン "G" を D、E、および F を使用せずにリポジトリ A にマージする最も簡単な方法は何ですか (G は D、E、または F に依存していないと仮定します)。

Repo A: A - B - C

Repo B (Clone of A) A - B - C - D - E - F - G

パッチは最善の策ですか?

4

2 に答える 2

79

トンファー そうです。あなたが説明しているのは「マージ」(または「プッシュ」または「プル」)ではありません。それは「チェリーピッキング」です。プッシュまたはプルは、すべての変更セットをあるレポから、まだそのレポにない別のレポに移動します。「マージ」は 2 つの「ヘッド」を取り、それらを両方の組み合わせである新しい変更セットにマージします。

本当に G を移動する必要があるが、そこに D、E、F があることに耐えられない場合は、レポ A から G を「hg エクスポート」し、レポ A で「hg インポート」する必要があります。Transplant拡張機能はラッパーです。同じ変更セットを複数回移動するのを避けるために、いくつかの細かい点でエクスポート/インポートします。

ただし、一般的にインポート/エクスポート、移植、およびチェリー ピッキングを使用することの欠点は、先祖なしでは実際に G を移動できないことです。Mercurial では、チェンジセットの名前はその親のハッシュドを含む「ハッシュド」であるためです。 . 異なる親 (G の新しい親は F ではなく C になります) は、別の hashid を意味するため、もはや G ではありません。これは G の作業ですが、名前による新しい変更セットです。

G を何か新しいものとして移動すること、それを G' (ジー素数) と呼びましょう。用途によっては大したことではありませんが、他の用途にとっては大きなピタです。すぐにレポ B が新しい変更セット H を取得し、それをその親の上に移動したい場合、G から G' に変更されます。これは異なるハッシュを持ちます。これは、H が H' として移動することを意味します。つまり、100 個の変更セットが行の下にあり、レポ A に D、E、F があることに耐えられなかったため、すべてに対して異なるハッシュ ID を持つことになります。

レポ A からレポ B に物を移動したい場合 (以前の移動とは反対の方向) に、事態はさらに悪化します。A から B への単純な「hg プッシュ」を実行しようとすると、G' (および H' と後続の子孫) が取得されます。これは、レポ B に既にある変更セットの複製になります。

では、あなたの選択肢は何ですか?

  1. 気にしないでください。 データはまだそこにあり、名前が異なる同じ変更セットが作成され、2 つのリポジトリ間の将来の交換でさらに多くの作業が行われます。それは間違っているわけではありません。ちょっと不器用かもしれませんが、気にしない人もいます。
  2. D、E、および F のすべてをレポ A に 移動します。すべての変更セットが無害であり、すべての面倒を回避できる場合は移動できます。それらがそれほど無害でない場合は、それらを移動してから、「hg backout」を実行して、新しい変更セット H で D、E、および F の効果を元に戻すことができます。
  3. まず、G により良い親子関係を与えます。 このルートに行くには遅すぎるので、これに言及するのは意地悪です(履歴を編集せずに)。変更セット G に取り掛かる前にすべきことは、 hg update C. G が変更セット D、E、および F に依存していない、または要求していない場合、それは彼らの子供であってはなりません。

代わりに、最初に C に更新すると、次のようなグラフが表示されます。

A - B - C - D - E - F
          \
            G

その場合、この質問に対する全体的な答えはhg push -r G ../repoA、G が同じハッシュ ID を維持したままきれいに移動し、D、E、および F がそれに対応しないということです。

アップデート:

コメントで指摘されているように。最新の Mercurial では、hg graftコマンドはこれを行うのに最適な方法です。

于 2009-11-04T04:32:09.917 に答える