16

我不使用 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在开发人员之间同步文件。

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

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

4

2 回答 2

20

版本控制.hgtags文件允许您

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

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

  • 你这样写

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

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

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

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

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

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

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

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

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

我希望这能有所帮助。

于 2009-06-07T15:11:01.863 回答
1

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

于 2010-02-10T23:16:30.177 回答