2012-02-19 14 views
5

私は複雑なhgリポジトリで複雑なマージをしようとしています。私は、Mercurialがマージを実行するための「ベース」として使用することを選択した「最新の共有祖先」に満足していません。'hg merge'で使用するマージベースを指定するには

私は自分の選択の特定のコミットをベースとして使用するように指定したいと思います。

これは可能ですか?あれば、どうですか?

答えて

14

Mercurial 3.0:マージベースとして使用する祖先を選択できるようになりました。あなたはmerge.preferancestorを設定することでそれを行います。これが理にかなっているとき、Mercurialはそれについてあなたに伝えます。以下の例では、あなたが見るであろう:バージョン3.0の前に

$ hg merge 
note: using eb49ad46fd72 as ancestor of 333411d2f751 and 7d1f71140c74 
     alternatively, use --config merge.preferancestor=fdf4b78f5292 
merging x 
0 files updated, 1 files merged, 0 files removed, 0 files unresolved 
(branch merge, don't forget to commit) 

のMercurial:レイジーアナグマは、コマンドラインからそれを使用するときにはMercurialが選んだ祖先を選ぶことができないことが正しいです。ただし、内部的にそれを行うことができ、それは、このための拡張機能を記述するためにあまりにも難しいことではありません。

from mercurial import extensions, commands, scmutil 
from mercurial import merge as mergemod 

saved_ancestor = None 

def update(orig, repo, node, branchmerge, force, partial, ancestor=None): 
    if saved_ancestor: 
     ancestor = scmutil.revsingle(repo, saved_ancestor).node() 
    return orig(repo, node, branchmerge, force, partial, ancestor) 

def merge(orig, ui, repo, node=None, **opts): 
    global saved_ancestor 
    saved_ancestor = opts.get('ancestor') 
    return orig(ui, repo, node, **opts) 

def extsetup(ui): 
    extensions.wrapfunction(mergemod, 'update', update) 
    entry = extensions.wrapcommand(commands.table, 'merge', merge) 
    entry[1].append(('', 'ancestor', '', 'override ancestor', 'REV')) 

はファイルでこれを入れて、拡張をロードします。

hg merge --ancestor X 

を使用して、通常の祖先を無効にすることができます。あなたが見つけたように、このになります。可能な祖先がいくつかある場合は違いがあります。そのような状況は、十字架の合併がある場合に発生します。あなたはこれらのコマンドで、このようなケースを作成することができます

hg init; echo a > x; hg commit -A -m a x 
hg update 0; echo b >> x; hg commit -m b 
hg update 0; echo c >> x; hg commit -m c 
hg update 1; hg merge --tool internal:local 2; echo c >> x; hg commit -m bc 
hg update 2; hg merge --tool internal:local 1; echo b >> x; hg commit -m cb 

グラフは次のようになります。

@ changeset: 4:333411d2f751 
|\ 
+---o changeset: 3:7d1f71140c74 
| |/ 
| o changeset: 2:fdf4b78f5292 
| | 
o | changeset: 1:eb49ad46fd72 
|/ 
o changeset: 0:e72ddea4d238 

あなたが正常にマージする場合は、祖先としてチェンジeb49ad46fd72を取得し、ファイルxが含まれています:

a 
c 
b 
c 

代わりにhg merge --ancestor 2を使用すると、別の結果が得られます。

どちらの場合でも、私のKDiff3は、競合を報告することなく自動的にマージを処理することができました。私が "再帰的な"マージ戦略を使用して、祖先としてe72ddea4d238を選ぶと、私は分かりやすい対立を提示されます。 Gitはデフォルトで再帰的マージ戦略を使用します。

+0

ワウです!完璧に動作します。どうもありがとうございました。実際、なぜこの機能がMercurialに含まれていないのか分かりません。ほとんどの場合、それを必要としませんが、必要な場合には、数時間の競合を解決したり、誤った自動マージを防ぐことさえできます。私はちょうどrepoの不正確な変更の後でそのような問題に遭遇しました。 –

-1

あなたはできません。あなたがマージを実行すると、あなたが行くことができる再考える(あなたのロジック・ベース・ショー/ ME /間違った仮定およびソリューションパスので)したくない場合は、最新の共有祖先は、あなたのマージ

ため本当のベースであるため、クローン - rebase-merge-export-importパッチルート

+3

"同等に良い"が異なる複数の候補共有祖先が存在する可能性があります。 http://man.he.net/man1/git-merge-baseを参照してください。 –

+0

@LucasMeijer - 1. Git 2ではなくMercurialについて述べました。**最新の祖先は*「より細かい」* –

+2

最新のものが最も良いものであることを知る理由は何ですか?今、それを知る方法はありません。 (普通は新しいものがベストです)。 gitのリンクは単に最高のものがない状況を示しています。まさに同じ水銀で起こりうる状況です。 –

1

ベースはマージツールの別の入力として使用されます。マージツールのコンフィグレーションでpremergeを無効にした場合(競合が発生していない場合には「明白な選択」となります)、マージツールを手動で起動して、ローカル、リモート、ベースの3つのリビジョンのコピーを手動で提供します。あなたのマージツールで何をしたいのですか?マージには、左側の親と右側の親だけが実際に記録されます。

+0

、私は完全に手動のルートに行くことができます、そして、それぞれのmergeconflictのために、私が望むベースにペーストを手動でコピーしてください。私は20以上のマージ競合を見ていますが、何かを自動的に把握できなければならないと考えました。 –

関連する問題