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

查看:18
本文介绍了如何在 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

每个标签只引用一个变更集,所以这里没有冲突.合并当然应该是两个文件的联合:

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

  • 真正的冲突:有一个分支

    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}
    " > .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}
    "
    

    它为每个标签输出一行,而不是变更集.您将此样式保存在某处并配置合并工具:

    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中有真正的冲突,那么上面的方法会默默地从最近的head中挑选标签 给你.合并工具基本上将hg tags保存在.hgtags中,hg tags多头的行为是在维基中解释.由于 hg tags 无条件地读取并静默合并来自所有 head 的 .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天全站免登陆