【问题标题】:How can I always know about all tags in Mercurial?如何始终了解 Mercurial 中的所有标签?
【发布时间】:2010-10-31 22:26:23
【问题描述】:

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

标签只是变更集的昵称(“变更集”实际上是指变更集产生的状态)。凉爽的。从标签到变更集 ID 的映射存储在 .hgtags 文件中。也很酷。 .hgtags 文件是版本化的。

什么?

这有很多违反直觉的后果。例如,如果我提交了一个我想要标记的变更集(例如,将形成版本 1.0 的代码),我必须在标记后再次提交,以将更新的标记文件放入存储库。如果我稍后更新到该标记的变更集,则工作副本将不包含该标记的任何知识。如果我做了一些工作,从而创建了一个新分支(例如,对于错误修复,朝着 1.1 前进),那么该分支将不知道它所生长的标签。除非我手动复制它。

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

我能做什么?

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

这些解决方案似乎都不是很好。我该怎么办?

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

【问题讨论】:

  • @SilentGhost:我删除了“hg”标签,因为“mercurial”标签使用得更多。但也许这是个错误?

标签: mercurial tags dvcs


【解决方案1】:

标记方法的选择肯定有一些奇怪的副作用,但它们在this wiki 中得到了很好的解释。还建议您克隆整个 repo,然后更新到感兴趣的点,以避免您创建的 repo 不包含用于创建它的标签的情况。

【讨论】:

    【解决方案2】:

    .hgtags 文件进行版本控制允许您

    • 编辑标签并查看谁编辑了它们(以及为什么他们留下了正确的提交消息)
    • 使用正常机制在存储库之间传输标签

    但是,这里发生了一些混乱。

    • 你写的

      [...] 如果我稍后更新到该标记的变更集,则工作副本将不包含该标记的任何知识。 [...]

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

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

    在开始使用它们之前,请确保您了解命名分支的含义。它们实际上不是制作错误修复分支所必需的。相反,您可以选择简单地返回 (hg update 1.0) 并修复错误然后提交。这将创建一个新的头部,你的开发线朝着 1.1(这给你multiple heads)。因此,您无需创建命名分支即可将新的开发分支添加到您的存储库。

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

    % hg clone -r X-head repo repo-X
    

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

    Named branches 相似,但又不同。它们允许您在每个变更集中嵌入一个命名。因此,您的历史记录中可以有多个名为“foo”的变更集。当您执行hg update foo 时,您最终将处于这些变更集的最顶端。这样,命名分支就起到了一种浮动标签的作用。

    如果您对更改集的永久标签的想法感到不舒服,您可以尝试使用bookmarks extension。这也会为您提供可用于更新的“浮动标签”,但它们不会永久成为历史记录的一部分,因为它们没有版本控制。

    我希望这会有所帮助。

    【讨论】:

    • 啊哈!马丁,感谢您清理可见标签集的来源 - 我的问题完全消失了。我同意您关于命名分支的观点,即您不必为分支命名就可以存在。我的直觉是未命名的分支会导致混乱(已经提交了基于 1.0 的错误修复变更集,如果您随后更新到其他内容,您如何回到错误修复行 - 您不必知道变更集 ID 吗? ),但当然我还没有在实践中尝试过。
    • 你是对的,你必须知道变更集 ID。 “hg head”可以告诉你,书签扩展可以给他们一个名字。使用多个克隆的最简单方法,就像我们在 Mercurial 项目本身中所做的那样。那里我们有 hg 和 hg-stable 的克隆和错误修正进入 hg-stable。我们也可以使用命名分支,我想我们不会,因为命名分支是在使用 hg/hg-stable 方案很久之后添加的。
    • 我们现在在 Mercurial 项目本身中使用命名分支。此外,书签扩展现在是核心功能的一部分,这意味着它在您升级到 Mercurial 1.8 后始终处于启用状态。
    • 我想当 Mercurial 项目切换的时候,有一些关于它的讨论;如果是这样,有什么地方我可以读到吗?看到最了解这些工具的人讨论这两种方法的优点会非常有趣。
    • 如果我要将在hg heads 中的每个变更集中找到的所有.hgtags 文件从最旧到最新进行连接,每个标签的最后一行是否与hg tags 匹配?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    相关资源
    最近更新 更多