6

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

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

这可能吗?如果可以,怎么做?

4

3 回答 3

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)

Mercurial 3.0 之前的版本: 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 默认使用递归合并策略。

于 2012-02-24T12:29:57.637 回答
1

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

于 2012-02-19T17:24:05.153 回答
-1

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

如果您想执行合并并且不想重新考虑(因为您的逻辑库显示 /me/ 错误的假设和解决方案路径),您可以使用 clone-rebase-merge-export-import 补丁路线

于 2012-02-19T16:55:47.847 回答