Ale*_*nov 21 merge mercurial dvcs merge-conflict-resolution .hgtags
我有一个脚本在构建服务器上以非交互模式运行一些Mercurial命令.其中一个命令合并两个分支,并且.hgtags
由于构建脚本的设置方式,在合并期间文件中始终存在冲突.
如何强制Mercurial始终.hgtags
使用两个文件中的更改合并文件,首先是一个文件,另一个是另一个文件?
例如,如果我要合并的文件是
A
B
C
Run Code Online (Sandbox Code Playgroud)
和
A
B
D
Run Code Online (Sandbox Code Playgroud)
我希望结果如此
A
B
C
D
Run Code Online (Sandbox Code Playgroud)
我猜我需要一个自定义合并工具.什么工具提供此功能?
Mar*_*ler 31
请参阅以下 Magras de La Mancha 的答案,以获得Mercurial 3.1的更好解决方案.对于旧版本的Mercurial,下面是一个更简单,更天真的解决方案.
是的,您需要为您的文件配置自定义合并工具.hgtags
.Mercurial不提供任何特殊的合并工具.hgtags
,您可以使用普通的三向合并工具手动合并它.
.hgtags
文件中的冲突可以有两种类型:
愚蠢的冲突:这是你的情况,这里没有真正的冲突.会发生什么是一个分支有
f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
12e0fdbc57a0be78f0e817fd1d170a3615cd35da C
Run Code Online (Sandbox Code Playgroud)
而另一个分支有
f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
979c049974485125e1f9357f6bbe9c1b548a64c3 D
Run Code Online (Sandbox Code Playgroud)
每个标记只涉及一个变更集,因此这里没有冲突.合并当然应该是两个文件的联合:
f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
12e0fdbc57a0be78f0e817fd1d170a3615cd35da C
979c049974485125e1f9357f6bbe9c1b548a64c3 D
Run Code Online (Sandbox Code Playgroud)真正的冲突:有一个分支
f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
12e0fdbc57a0be78f0e817fd1d170a3615cd35da C
Run Code Online (Sandbox Code Playgroud)
而另一个分支有
f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
979c049974485125e1f9357f6bbe9c1b548a64c3 C
Run Code Online (Sandbox Code Playgroud)
这里存在一个真正的冲突:hg tag C
在两个分支上完成,但标签指的是不同的变更集.解决这个问题是一项手动任务.
如果您可以保证只会遇到愚蠢的冲突,并且每个变更集只有一个标签,那么您可以使用
hg log -r "tagged()" --template "{node} {tags}\n" > .hgtags
Run Code Online (Sandbox Code Playgroud)
生成一个新.hgtags
文件.关键的见解是Mercurial 知道如何在内部合并标签!当你有两个不同.hgtags
文件的头时,它会一直这样做.上述模板只是.hgtags
根据此内部合并生成一个新文件.
如果您有可能每变更一个以上的标签,则上述不会工作-所有的标签都印上一条线,所以你得到一个标签foo bar
,而不是两个标签foo
和bar
.然后,您可以使用此样式文件:
changeset = "{tags}"
tag = "{node} {tag}\n"
Run Code Online (Sandbox Code Playgroud)
它为每个标签输出一行,而不是变更集.您可以在某处保存此样式并配置合并工具:
[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
Run Code Online (Sandbox Code Playgroud)
您现在有自动标记合并.有一些警告:
三个或更多头:只有在合并时有两个头,这项技术才有效.如果您有三个或更多头,则可能会重新显示已删除的标签.如果你有头X,Y和Z,并且标签A
在X中被删除,那么Mercurial通常能够找出A
整体删除的标签.它基于X 000...0 A
中.hgtags
文件中的一行来执行此操作.但是,如果合并X和Y以获得W,则建议的方法将不包含任何此类000...0 A
行.A
来自Z 的定义现在将突然生效并重新引入A
.
真正的冲突:如果你有真正的冲突.hgtags
,那么上面的方法将默默地从你最近的头上挑选标签.合并工具基本上保存hg tags
在.hgtags
,并且行为hg tags
与多头是在维基解释.由于hg tags
无条件地.hgtags
从所有头部读取并静默地合并文件,因此使用这种简单的方法我们无能为力.处理此问题需要更大的脚本来读取这两个.hgtags
文件并检测冲突.
mag*_*ras 12
Mercurial 3.1(2014-08-01)介绍了内部:tagmerge.它被标记为实验所以要小心.以下是changeset的序言(如果您按照链接,可以找到有关算法的更多详细信息):
添加一个新的internal:tagmerge合并工具,它为mercurial的标记文件实现自动合并算法
tagmerge算法能够解决当前会触发.hgtags合并冲突的大多数合并冲突.它不能(也不能)处理的唯一情况是,其中两个标签指向每个合并父级上的不同修订,并且它们相应的标记历史具有相同的级别(即相同的长度).在所有其他情况下,合并算法将选择属于具有最高排名标记历史的父级的修订.合并的标记历史记录是两个标记历史记录的组合(特别注意尝试在可能的情况下组合常见的标记历史记录).
该算法还处理从.hgtags文件和其他类似的极端情况中手动删除标记的情况.
除了实际合并来自两个父项的标记之外,考虑到基数,该算法还尝试最小化合并标记文件与第一个父标记文件之间的差异(即,它尝试使合并标记顺序与可能是第一个父级的标签文件顺序).
tagmerge仅适用于标记文件,因此要使用它,您应该设置合并模式.要在每个命令的基础上执行此操作,请使用--config选项:
hg merge -r REV --config merge-patterns..hgtags=internal:tagmerge
或者在每个存储库的基础上执行此操作添加到您的repo配置.hg/hgrc
:
[merge-patterns]
.hgtags=internal:tagmerge
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4416 次 |
最近记录: |