我正在尝试在复杂的 hg 存储库中进行复杂的合并。我对 Mercurial 选择用作执行合并的“基础”的“最新共享祖先”不满意。
我想指定一个我自己选择的特定提交作为基础。
这可能吗?如果可以,怎么做?
我正在尝试在复杂的 hg 存储库中进行复杂的合并。我对 Mercurial 选择用作执行合并的“基础”的“最新共享祖先”不满意。
我想指定一个我自己选择的特定提交作为基础。
这可能吗?如果可以,怎么做?
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 默认使用递归合并策略。
Base 仅用作合并工具的另一个输入。如果您premerge
在合并工具配置中禁用(premerge 在没有冲突时为您做出“明显的选择”)并手动调用合并工具,提供您想要的 3 个修订版本的副本作为本地、远程和基础,您可以获得任何你想要在你的合并工具中。只有左父和右父实际记录在合并中。
你不能这样做。因为最新的共享祖先是您合并的真正基础
如果您想执行合并并且不想重新考虑(因为您的逻辑库显示 /me/ 错误的假设和解决方案路径),您可以使用 clone-rebase-merge-export-import 补丁路线