最大的区别是分支名称在历史记录中的记录方式。对于命名分支,分支名称嵌入在每个变更集中,因此将成为历史的不可变部分。使用克隆将不会永久记录特定变更集的来源。
这意味着克隆非常适合您不想记录分支名称的快速实验,而命名分支适用于长期分支(“1.x”、“2.x”等)。
另请注意,单个存储库可以轻松容纳 Mercurial 中的多个轻量级分支。可以将此类存储库中的分支添加为书签,以便您可以轻松地再次找到它们。假设您已经克隆了公司存储库,它看起来像这样:
[a] --- [b]
您破解并制作[x]
and [y]
:
[a] --- [b] --- [x] --- [y]
意思是当有人放入存储库时[c]
,[d]
所以当你拉取时,你会得到一个这样的历史图表:
[x] --- [y]
/
[A B C D]
这里在一个存储库中有两个头。您的工作副本将始终反映单个变更集,即所谓的工作副本父变更集。检查这个:
% hg parents
假设它报告[y]
. 你可以看到头
% hg heads
这将报告[y]
和[d]
。如果您想将您的存储库更新为 的干净签出[d]
,那么只需执行([d]
用修订号替换[d]
):
% hg update --clean [d]
然后您将看到该hg parents
报告[d]
。这意味着您的下一次提交将[d]
作为父提交。因此,您可以修复您在主分支中注意到的错误并创建变更集[e]
:
[x] --- [y]
/
[a] --- [b] --- [c] --- [d] --- [e]
要仅推送变更集[e]
,您需要执行
% hg push -r [e]
[e]
变更集哈希在哪里。默认情况下hg push
,将简单地比较存储库并查看[x]
、[y]
和丢失,[e]
但您可能还不想共享。[x]
[y]
如果错误修复也影响了您,您希望将其与您的功能分支合并:
% hg update [y]
% hg merge
这将使您的存储库图如下所示:
[x] --- [y] ----------- [z]
//
[a] --- [b] --- [c] --- [d] --- [e]
和[z]
之间的合并在哪里。您也可以选择丢弃分支:[y]
[e]
% hg strip [x]
我这个故事的主要观点是:一个克隆可以很容易地代表几个发展轨迹。在不使用任何扩展的情况下,“plain hg”始终如此。不过,书签扩展是一个很大的帮助。它将允许您为变更集分配名称(书签)。在上述情况下,您需要一个书签在您的开发头上,一个在上游头上。书签可以使用 Mercurial 1.6 进行推送和拉取,并且已成为 Mercurial 1.8 中的内置功能。
[x]
如果您选择制作两个克隆,您的开发克隆在制作and后将如下所示[y]
:
[a] --- [b] --- [x] --- [y]
您的上游克隆将包含:
[a] --- [b] --- [c] --- [d]
您现在注意到错误并修复它。在这里您不必这样做,hg update
因为上游克隆已准备好使用。您提交并创建[e]
:
[a] --- [b] --- [c] --- [d] --- [e]
要在您的开发克隆中包含错误修复,请将其拉入其中:
[a] --- [b] --- [x] --- [y]
\
[c] --- [d] --- [e]
并合并:
[a] --- [b] --- [x] --- [y] --- [z]
\ /
[c] --- [d] --- [e]
该图可能看起来不同,但它具有相同的结构并且最终结果是相同的。使用克隆,您必须少做一些心理簿记。
命名分支在这里并没有真正出现,因为它们是可选的。在我们改用命名分支之前,Mercurial 本身是使用两个克隆开发的。除了“默认”分支之外,我们还维护一个名为“稳定”的分支,并基于“稳定”分支发布我们的版本。有关推荐工作流程的描述,请参阅 wiki 中的标准分支页面。