2012-03-20 53 views
19

我有一个脚本在构建服务器上以非交互模式运行一些Mercurial命令。其中一个命令会合并两个分支,并且在合并期间.hgtags文件中始终存在冲突,这是因为构建脚本的方式。如何在Mercurial中自动合并.hg标签?

如何强制Mercurial始终使用来自两个文件的更改合并.hgtags文件,先从一个文件然后从另一个文件进行更改?

例如,如果我合并文件是

A 
B 
C 

A 
B 
D 

我想的结果是

A 
B 
C 
D 

我猜我需要一个自定义合并工具。什么工具提供此功能?

回答

31

请参阅answer below通过Magras德拉曼恰与水银3.1更好的解决方案。以下是针对旧版Mercurial的更简单更幼稚的解决方案。


是的,你需要配置自定义merge tool.hgtags文件。 Mercurial没有为.hgtags提供任何特殊的合并工具,您可以使用常规的三向合并工具手动合并它。

冲突在.hgtags文件可以有两种类型:

  • 傻冲突:这是你的情况并没有真的在这里发生冲突。什么情况是,一个分支具有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C 
    

    ,另一支有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    979c049974485125e1f9357f6bbe9c1b548a64c3 D 
    

    每个标签代表一个确切的变更,所以这里没有冲突。当然,合并应该是工会上的两个文件:

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C 
    979c049974485125e1f9357f6bbe9c1b548a64c3 D 
    
  • 真实冲突:有一个分支有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C 
    

    ,另一支有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    979c049974485125e1f9357f6bbe9c1b548a64c3 C 
    

    这里有一个真正的冲突:hg tag C在两个分支上完成,但t ags指的是不同的变更集。解决这个问题是一项手动任务。

如果你能保证你只有傻冲突和你只有每一个变更标签,那么你可以使用

hg log -r "tagged()" --template "{node} {tags}\n" > .hgtags 

生成一个新文件.hgtags。关键的洞察是Mercurial 知道如何在内部合并标签!当你有两个不同的.hgtags文件头时,它总是这样做。上述模板仅基于此内部合并生成新的.hgtags文件。

如果可能每变更一个以上的标签,则上述不会工作 - 所有的标签都印上一条线,所以你得到一个标签foo bar,而不是两个标签foobar的。然后,您可以使用此style file代替:

changeset = "{tags}" 
tag = "{node} {tag}\n" 

它输出每标签一条线,而不是变更集。在某处保存此样式并配置合并工具:

[merge-tools] 
hgtags.executable = hg 
hgtags.args = log -r "tagged()" --style ~/tmp/tags-style > $output 
hgtags.premerge = False 
hgtags.priority = -1000 

[merge-patterns] 
.hgtags = hgtags 

您现在已经自动标记合并。还有一些注意事项:

  1. 三个或更多的头:如果您在合并时有两国元首该方法仅适用。如果您有三个或更多头,则可能会重新显示已删除的标签。如果您有头X,Y和Z,并且标记A在X中被删除,则Mercurial通常能够确定总体上删除了A。它基于X的.hgtags文件中的000...0 A行执行此操作。但是,如果您将X和Y合并为W,则建议的方法将不包含任何此类000...0 A行。来自Z的A的定义现在会突然生效并重新引入A

  2. 真实冲突:如果您有.hgtags真正的冲突,那么上面的方法将默默地挑标签从最近的头部你。合并工具基本上将hg tags保存在.hgtags中,并且具有多个头的hg tags的行为是explained in the wiki。由于hg tags无条件地读取并默默合并来自所有主管的.hgtags文件,因此使用这种简单的方法我们无能为力。处理这个问题需要一个更大的脚本来读取两个.hgtags文件并检测冲突。

+0

有关解决愚蠢冲突的合并工具,请参阅https://bitbucket.org/xrstf/tagsmerger/wiki/Home。 :) – xrstf 2012-03-20 11:11:25

+0

@xrstf:其实我前几天看到了这个。我不推荐它,因为我认为在有两个以上的人头时它不能正常工作。简单地删除'000 ... 0'行将重新引入标签,就像我在我的答案中解释的那样。 – 2012-03-20 12:05:02

+0

非常好,我鼓掌!我可以问,这些notrs会出现在Aragost的网站上吗?我们会在这里丢失它 – 2012-03-21 00:38:50

-2

你应该试试diffmerge,太棒了!

+2

我觉得OP正在寻找一种**自动**合并这些文件的方法。 – krtek 2012-03-20 07:06:12

+0

对于*方式*,您可以随意编辑冲突的文件,但如果涉及很多冲突,那将会很头疼,这就是为什么我推荐一个像* diffmerge *这样的好工具。没有这样的工具可以帮助你自动解决冲突,一个工具会帮助你这样做。 – neevek 2012-03-20 07:12:55

1

无法通过执行无人参与合并来自动解决合并冲突。没有合并(即选择“只有我”或“只有其他”)它将起作用。

恐怕你的计划工作流程糟糕 - 建立服务器一定不要执行任何操作,哪些修改源。这是人类和人类选择的任务。

但我想,.hgtags中的确切数据必须为构建服务器(它使用自己的克隆,而不是任何人填充,我希望?!),因此您可以在命令中定义任何合并策略,并具有坏,用数据丢失).hgtags以任何语言合并

顺便说一句,“首先从一个,然后从其它”,仅使用形式逻辑,用于对

A 
B 
C 

A 
B 
D 

表示ABCABD导致

+1

在解决冲突的情况下,“首先从一个,然后从另一个”通常是指在结果文件中使用来自两个文件的_conflicted_行:首先从一个文件,然后从另一个文件。这是任何图形合并工具的标准功能,所以我认为之前使用过的所有人都会理解我的意思。 – 2012-03-20 07:50:52

+1

这是正确的“在大多数情况下”,但正如@MartinGeisler所建议的,在这种特殊情况下存在解决方案。另外,您不应该在不了解更多的情况下批评OP工作流程。 – krtek 2012-03-20 08:50:39

+2

@krtek - 构建服务器不能修改代码,只能构建。我保留向所有人陈述真相的权利 – 2012-03-20 09:31:47

1

实际上您并不需要合并.hgtags文件。它可以在不同分支上有所不同,Mercurial将正确列出所有分支中的所有标签。

我们使用merge-patterns configuration option来告诉Mercurial在合并.hgtags时使用本地分支。以下内容添加到您的存储库的hgrc文件:

[merge-patterns] 
.hgtags = internal:local 

在做涉及.hgtags文件合并,.hgtags将显示为修改,但不能改变的。

+1

不是一个好主意,你可以从另一个头上松开标签。 – Jesse 2014-05-27 08:54:00

10

Mercurial 3.1(2014-08-01)介绍internal:tagmerge。它被标记为实验,所以要小心。 这里是changeset序言(你可以找到关于算法的详细信息,如果您按照链接):

添加一个新的内部:tagmerge合并工具,它实现了一个自动合并算法善变的标记文件

的tagmerge算法能够解决目前会触发.hgtags合并冲突的大多数合并冲突。它没有(也不能)处理的唯一情况是其中两个标签指向每个合并父亲上的不同修订,其相应的标签历史具有相同的等级(即相同的长度)。在所有其他情况下,合并算法将选择属于具有最高排名标记历史的父级的修订。合并标签历史记录是两个标签历史记录的组合(特别注意尽可能将常见标签历史记录组合在一起)。

该算法还处理标签已被手动从.hgtags文件和其他类似的角落案件中删除的情况。

除了实际合并来自两个父母的标签,考虑到基础,算法还尝试最小化合并标签文件和第一个父标签文件之间的差异(即,它试图使合并标签顺序尽可能与第一个父母的标签文件订单相似)。

tagmerge只标记文件的工作,所以使用它,你应该设置合并图案。要做到这一点每命令依据使用--config选项:

hg merge -r REV --config merge-patterns..hgtags=internal:tagmerge

还是要做到这一点每库基础上添加到您的回购配置.hg/hgrc此:

[merge-patterns] 
.hgtags=internal:tagmerge 
+0

Mercurial的新版本在合并涉及'.hgtags'文件时默认使用这种算法? – binki 2015-10-13 19:38:33

+0

@binki,我没有看mer​​curial路线图或邮件列表。一年前刚刚解决了这个问题,并且找到了我找到的解决方案。 – magras 2015-10-15 14:14:48