我如何始终知道Mercurial中的所有标记?

我如何始终知道Mercurial中的所有标记?,mercurial,tags,dvcs,Mercurial,Tags,Dvcs,我不使用Mercurial,但我想开始,所以我正在阅读有关它的文章。我唯一广泛使用的SCM系统是CVS。我读到的关于Mercurial的大部分内容都是有道理的,而且听起来不错。但我对它的这种做法时而震惊,时而困惑 标记只是变更集的昵称(所谓“变更集”,实际上是指变更集产生的状态)。酷。从标记到变更集ID的映射存储在.hgtags文件中。也很酷。.hgtags文件已进行版本控制 什么 这有很多违反直觉的后果。例如,如果我提交了一个我想标记的变更集(比如,将形成1.0版的代码),我必须在标记后再次提

我不使用Mercurial,但我想开始,所以我正在阅读有关它的文章。我唯一广泛使用的SCM系统是CVS。我读到的关于Mercurial的大部分内容都是有道理的,而且听起来不错。但我对它的这种做法时而震惊,时而困惑

标记只是变更集的昵称(所谓“变更集”,实际上是指变更集产生的状态)。酷。从标记到变更集ID的映射存储在
.hgtags
文件中。也很酷。
.hgtags
文件已进行版本控制

什么

这有很多违反直觉的后果。例如,如果我提交了一个我想标记的变更集(比如,将形成1.0版的代码),我必须在标记后再次提交,以将更新的标记文件放入存储库。如果我在以后的某个日期更新到标记的变更集,工作副本将不包含任何关于该标记的知识。如果我做了一些工作,从而建立了一个新的分支(比如,对于bug修复,走向1.1),那么该分支将不知道它从哪个标签成长而来。除非我手动复制它,那就是

随着在原始主干和我的新分支上的开发继续进行,并创建标记来标记重要的变更集(主干上的2.0版本,分支上的1.1和1.2错误修复版本),这两个分支将继续进行,而忽略另一个分支的标记。因此,如果我在一个分支上完成了工作,并且想要切换到另一个分支上的某个特定变更集(比如,我完成了1.2错误修复版本,但现在必须从2.1错误修复开始,基于2.0),我现在已经吃饱了。我当前的变更集不知道2.0

我能做什么

  • 我可以让从事2.x分支工作的人读出2.0的实际变更集ID,并明确使用它,但这太可怕了
  • 我可以命名我的分支,也可以使用标记,这样我就可以跳到2.x分支的头部,从而了解新标记,然后跳回到2.0标记。假设分支与标记不同,是普遍可见的,是这样吗?即使是这样,这看起来也很笨重
  • 我可以在存储库外维护一个全局
    hgtags
    文件,并使用几个钩子在更新时引入一个副本,覆盖本地副本,以及在提交时复制回任何更改。我不确定这在多用户环境中如何工作,在这个环境中,开发人员正在将更改推送到共享存储库;我可能需要一个单独的存储库来存储
    hgtags
    文件
  • 我可以使用本地标记,它位于版本控制机制之外,因此可以避免整个问题。与共享全局标记一样,我必须在开发人员之间设置一种机制来同步
    localtags
    文件
这些解决方案似乎没有一个是完全好的。我该怎么办


这里的一个假设是,我正在使用单个存储库中的命名分支来管理分支,而不是使用每个分支的存储库。如果我使用后者,情况会更好吗?

通过对
.hgtags
文件进行版本控制,您可以

  • 编辑标记并查看是谁编辑了它们(如果它们留下了正确的提交消息,为什么要编辑)
  • 使用正常机制在存储库之间传输标记
然而,这里有一些混乱

  • 你写的

    […]如果我在以后的某个日期更新到该标记的变更集,工作副本将不包含该标记的任何知识。[……]

    这是错误的,标签是从所有头中找到的
    .hgtags
    文件中收集的。这意味着您可以更新到旧标记(
    hg update 0.1
    ),但仍然可以看到所有标记(
    hg标记

  • 您询问分支是否普遍可见。是的,它们是——命名分支的名称可以在需要指定变更集的任何上下文中使用,标记也是如此

在开始使用命名分支之前,请确保您了解它们是什么。实际上,它们并不是生成错误修复分支所必需的。相反,您可以选择返回(
hgpupdate1.0
)修复错误,然后提交。这将创建一个新的头部,这是您的1.1开发线(这将为您提供)。因此,您不必创建命名分支来将新的开发分支添加到存储库中

拥有多个头部完全等同于拥有多个克隆。您甚至可以来回转换:您可以使用

% hg clone -r X-head repo repo-X
X-head
变更集及其祖先与
repo
中的其他变更集解开。您可以通过简单地将所有变更集拉入一个大克隆来组合多个克隆

它们既相似又不同。它们允许您在每个变更集中嵌入一个命名的。因此,您可以在历史记录中有几个名为“foo”的变更集。当您执行
hg update foo
时,您将最终处于这些变更集的顶端。通过这种方式,命名分支作为一种浮动标记发挥作用

如果您对变更集的永久性标签的想法感到不舒服,您可以试试。这也会给你“浮动标签”,你可以用它来更新,但它们不会永远成为历史的一部分,因为它们没有版本控制


我希望这能有所帮助。

选择标记方法肯定会有一些奇怪的副作用,但这些副作用在中得到了很好的解释。还建议您克隆整个回购协议,然后更新到关注点,以避免创建的回购协议不包含用于创建它的标记。

Aha!马丁,谢谢你澄清了这组可见标签的来源——我的问题完全消失了。我同意你关于命名分支的观点(你不必给一个分支命名,它就可以存在)。我的直觉是,未命名的分支会导致混乱(有