如何指定要在'hg merge'中使用的合并库

时间:2012-02-19 14:24:18

标签: version-control mercurial merge dvcs three-way-merge

我正在尝试在复杂的hg存储库中进行复杂的合并。我对Mercurial选择用作执行合并的“基础”的“最新共享祖先”不满意。

我想指定一个我自己选择的特定提交作为基础。

这是可能的,如果是的话,怎么样?

3 个答案:

答案 0 :(得分:15)

Mercurial 3.0:您现在可以选择要用作合并基础的祖先。您可以通过设置merge.preferancestor来实现。当有意义时,Mercurial会告诉你它。通过下面的示例,您将看到:

$ 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)

版本3.0之前的Mercurial: Lazy Badger是正确的,当您从命令行使用它时,您无法选择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,则会得到不同的结果:

a
b
c
b

在这两种情况下,我的KDiff3都能够自动处理合并而不报告任何冲突。如果我使用“递归”合并策略并选择e72ddea4d238作为祖先,那么我会遇到明显的冲突。 Git默认使用递归合并策略。

答案 1 :(得分:1)

Base仅用作合并工具的另一个输入。如果在合并工具配置中禁用premerge(premerge在没有冲突时为您做出明显选择)并手动调用合并工具,提供您想要的3个版本的副本作为本地,远程和基础,你可以在你的合并工具中得到你想要的任何东西。只有左父项和右项父项实际记录在合并中。

答案 2 :(得分:-1)

你不能这样做。因为最新的共享祖先 IS 是您合并的真正基础

如果你想执行合并而不想重新思考(因为你的逻辑基础显示/我/错误的假设和解决方案路径)你可以去克隆-robase-merge-export-import补丁路径