如何自动合并Mercurial中的.hgtags? [英] How to automatically merge .hgtags in Mercurial?

查看:105
本文介绍了如何自动合并Mercurial中的.hgtags?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本,该脚本在构建服务器上以非交互方式运行一些Mercurial命令.其中一个命令合并了两个分支,由于建立脚本的方式,在合并过程中.hgtags文件中总是存在冲突.

I have a script running some Mercurial commands in non-interactive mode on a build server. One of the commands merges two branches and there is always a conflict in the .hgtags file during the merge because of the way the build scripts are set up.

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

How can I force Mercurial to always merge the .hgtags file using changes from both files, first from one, then from the other?

例如,如果我要合并的文件是

For example, if I the files to merge were

A
B
C

A
B
D

我希望结果是

A
B
C
D

我猜我将需要一个自定义合并工具.哪些工具可以提供此功能?

I am guessing I will need a custom merge tool. What tool provides this functionality?

推荐答案

请参阅以下答案 Magras de La Mancha为使用Mercurial 3.1提供更好的解决方案.下面是针对较旧版本的Mercurial的更简单,更幼稚的解决方案.

Please see the answer below by Magras de La Mancha for better solution with Mercurial 3.1. The below is a simpler and more naive solution for older versions of Mercurial.

是的,您需要为.hgtags配置自定义合并工具文件. Mercurial没有为.hgtags提供任何特殊的合并工具,您应该使用常规的三向合并工具手动对其进行合并.

Yes, you need to configure a custom merge tool for your .hgtags file. Mercurial doesn't provide any special merge tool for .hgtags, you're expected to merge it by hand using your normal three-way merge tool.

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

Conflicts in the .hgtags file can have two types:

  • 严重的冲突:这是您遇到的情况,这里并没有真正的冲突.发生了什么事,一个分支有

  • Silly conflicts: This is the situation you have and there is not really a conflict here. What happens is that one branch has

f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
12e0fdbc57a0be78f0e817fd1d170a3615cd35da C

而另一个分支有

f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
979c049974485125e1f9357f6bbe9c1b548a64c3 D

每个标签仅指一个变更集,因此这里没有冲突.合并当然应该是两个文件中的 union :

Each tag refers to exactly one changeset, so there's no conflict here. The merge should of course be the union on of the two files:

f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
12e0fdbc57a0be78f0e817fd1d170a3615cd35da C
979c049974485125e1f9357f6bbe9c1b548a64c3 D

  • 实际冲突:有一个分支机构

  • Real conflicts: There one branch has

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C
    

    而另一个分支有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
    979c049974485125e1f9357f6bbe9c1b548a64c3 C
    

    这里确实存在冲突:hg tag C在两个分支上都完成了,但是标记引用了不同的变更集.解决此问题是一项手动任务.

    There is a real conflict here: hg tag C was done on both branches, but the tags refer to different changesets. Resolving this is a manual task.

    如果可以保证只发生严重冲突,并且每个变更集只有一个标签,则可以使用

    If you can guarantee that you'll only have silly conflicts and that you only have one tag per changeset, then you can use

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

    生成一个新的.hgtags文件.关键见解是Mercurial 知道如何在内部合并标签!当您有两个具有不同.hgtags文件的打印头时,它将一直执行此操作.上面的模板仅基于此内部合并生成一个新的.hgtags文件.

    to generate a new .hgtags file. The key insight is that Mercurial knows how to merge tags internally! It does this all the time when you have two heads with different .hgtags files. The above template simply generates a new .hgtags file based on this internal merge.

    如果每个变更集可能有多个标签,则以上操作将无法正常工作-所有标签都打印在一行上,因此您将获得一个标签foo bar而不是两个标签foobar.然后,您可以改用样式文件 :

    If you might have more than one tag per changeset, then the above wont work — all the tags are printed on one line so you get a tag foo bar instead of two tags foo and bar. You can then use this style file instead:

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

    每个 tag 输出一行,而不更改集.您可以将此样式保存在某处并配置合并工具:

    It outputs one line per tag, not changeset. You save this style somewhere and configure a merge tool:

    [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
    

    您现在可以进行自动标签合并.有一些警告:

    You now have automatic tag merges. There are some caveats:

    1. 三个或多个头部::该技术仅在合并时具有两个头部的情况下有效.如果您的头数超过三个,则可能会重新显示已删除的标签.如果您具有X,Y和Z头,并且标记A在X中被删除,那么Mercurial通常可以确定A总体上被删除.它基于X中.hgtags文件中的000...0 A行来执行此操作.但是,如果将X和Y合并以获得W,则建议的方法将不包含任何此类000...0 A行.从Z开始的A的定义现在将突然生效并重新引入A.

    1. Three or more heads: The technique only works if you have two heads at the time of merging. If you have three heads or more, it's possible for a deleted tag to re-appear. If you have heads X, Y, and Z, and the tag A is deleted in X, then Mercurial is normally able to figure out that A is deleted overall. It does this based on a 000...0 A line in the .hgtags file in X. However, if you merge X and Y to get W, then the approach suggested will not contain any such 000...0 A line. The definition of A from Z will now suddenly take effect and re-introduce A.

    实际冲突::如果您在.hgtags中存在实际冲突,则上述方法将为您静默地从最近的头中选择标签.合并工具基本上将hg tags保存在.hgtags中,并且hg tags具有多个头部的行为是在Wiki中进行了解释.由于hg tags无条件地读取并默默地合并了.hgtags文件,因此使用这种简单的方法我们无能为力.要解决此问题,将需要一个更大的脚本来读取两个.hgtags文件并检测到冲突.

    Real conflicts: If you have real conflicts in .hgtags, then the above method will silently pick the tag from the most recent head for you. The merge tool basically saves hg tags in .hgtags, and the behavior of hg tags with multiple heads is explained in the wiki. Since hg tags unconditionally reads and silently merges the .hgtags file from all heads, there's nothing we can do about it with this simple approach. Dealing with this would require a bigger script that reads the two .hgtags files and detects the conflict.

    这篇关于如何自动合并Mercurial中的.hgtags?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆