我想在复杂的hg资源库中进行复杂的合并。我对Mercurial选择用作“基础”来执行合并的“最新共享祖先”感到不满。我如何指定一个合并基在'hg合并'中使用
我想指定我自己选择的特定提交作为基础。
这是可能的,如果是这样,如何?
我想在复杂的hg资源库中进行复杂的合并。我对Mercurial选择用作“基础”来执行合并的“最新共享祖先”感到不满。我如何指定一个合并基在'hg合并'中使用
我想指定我自己选择的特定提交作为基础。
这是可能的,如果是这样,如何?
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)
水银。但是,您可以在内部完成,并且为此编写扩展并不难:
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默认使用递归合并策略。
你不能这样做。由于最新的共同的祖先IS真正为您的合并基础
如果你想进行合并,不希望重新考虑(因为你的逻辑基秀/ ME /错误的假设和解决方案的路径),你可以去clone-rebase-merge-export-import修补程序路由
可以有多个“同样好”但不同的候选共享祖先。见http://man.he.net/man1/git-merge-base – 2012-02-19 17:23:15
@LucasMeijer - 1.我们说关于Mercurial,而不是Git 2.他们不是**“同样好”,因为最新的祖先是*“更好”* – 2012-02-19 17:35:11
你有什么理由知道最新的是最好的。伊莫,没有办法知道这一点。 (尽管通常最新的是最好的)。 git链接仅仅说明了没有“最好”的情况,这种情况在mercurial中可能发生的情况也是如此。 – 2012-02-19 18:09:10
Base仅用作您的合并工具的另一个输入。如果在合并工具配置中禁用premerge
(在没有冲突时,premerge会为您提供“明显选择”),并手动调用合并工具提供您希望作为本地,远程和基础的3个修订版的副本,您可以获得无论你想在你的合并工具。只有左侧父母和右侧父母实际记录在合并中。
是啊,我可以去完全手动路由,并为每个mergeconflict,手动复制粘贴在我想要的基地。尽管如此,我正在考虑20多种合并冲突,并认为我们必须能够自动计算出某些事情。 – 2012-02-19 17:28:07
这是一个惊喜!完美的作品。非常感谢你。事实上,我不明白为什么这个功能不包含在Mercurial中。在大多数情况下,人们不需要它,但在必要的情况下,它可以节省数小时的冲突解决,甚至防止不正确的自动合并。我刚刚在回购不正确的更改后遇到这样的问题。 – 2013-03-07 10:12:19