我们目前使用的一个比较大的代码库颠覆。每个版本都有自己的分公司,并修复使用svnmerge.py
对树干进行,迁移到发布分支
我认为时机已到,移动到更好的源代码控制,我一直在用水银一会儿玩弄。
人们似乎对虽然管理这种释放结构中使用水银的两所学校。无论是每一个版本都有自己的回购和修复程序是针对版本分支上,并推到主分支(和任何其他较新的版本分支。),或使用一个单一的存储库中的命名分支(或多个匹配的副本。)
在这两种情况下,它看起来像我可能会使用类似移植东西cherrypick列入发布分支的变化。
我问你;什么是每种方法的优缺点?
最大的区别是分支名的方式记录在历史上。随着命名分支分支名称嵌入在每个变更,因此将成为历史的一部分不变。随着克隆会有的,其中一个特定的变更是从哪里来没有永久的记录。
这意味着,克隆是伟大的快速实验,你不想录制分支名,并命名为分支有利于长期分支(“1.x中”,“2.X”和类似)。
还需要注意的是单个存储库可以很容易地容纳在水银多个轻质分支。这种在存储库分支可以添加书签,这样你可以很容易地找到它们。比方说,你已经克隆了公司仓库时,它看起来是这样的:
[a] --- [b]
您谬以千里,使[x]
和[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]
我这个故事的主要观点是:单个克隆可以很简单地表示了几个发展轨道。这不使用任何扩展一直是“纯汞”真。该bookmarks extension是一个很大的帮助,虽然。它可以让你指定的名称(书签)来变更。在上述情况下,你会想你的开发头,一个在上游头一个书签。书签可以推动而随着水银1.6拉,已经成为水银1.8的内置功能。
如果您已经选择了让两个克隆,开发克隆看起来会是这样做[x]
和[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]
该图形的威力看起来不同,但具有相同的结构和最终的结果是一样的。使用你有克隆做少一点心理记账。
命名分支并没有真正走进图片浏览,因为他们是有相当可选。利用两个克隆之前,我们切换到使用命名分支水银本身进行多年开发。我们维持一个叫做除“默认”分支“稳定”分支,并根据该“稳定”分支我们的版本。对于建议的工作流程的说明,请参见维基的standard branching页面。
我想你想在一个回购整个历史。产卵掀起了短期回购是短期的实验,没有重大的事件,如版本。
一个水银的失望的是,似乎是要创造一个短暂的分支,玩它,放弃它,并收集垃圾没有简单的方法。分行是永远的。我很同情从来没有想放弃的历史,但超低价,一次性分支是一个git
功能,我真的想在hg
看到的。
你应该做两个。
先从@Norman接受的答案:使用一个存储库,每一个版本命名为分支。
然后,让每发布分支的一个克隆,用于构建和测试。
一个关键注意的是,即使你使用多个仓库,你应该避免使用transplant
,因为1)它改变了哈希它们之间移动的变更,以及2)它可能引入是非常困难的错误时有变更集之间的冲突的变化来检测你移植和目标分支。你想要做平常合并来代替(无premerge:始终目视检查合并),这将导致什么@mg他的回答的最后说:
该图形的威力看起来不同,但具有相同的结构和最终的结果是一样的。
更冗长,如果使用多个存储库中,“主干”仓库(或默认情况下,主,发展,等等)包含在所有库中的所有的变更。每次发布/分支库仅仅是在树干一个分支,所有合并退一方式或其他方式回主干,直到你想留下的旧版本。因此,在指定的分支方案,该方案主要回购和单回购之间的唯一真正的区别是分支根本就不管被命名与否。
这应该使之显而易见的,为什么我说:“开始一个回购”。这单一的回购只是你永远需要寻找在任何版本的任何变更的地方。您可以进一步在发布分支标签变更的版本。这是概念上简单明了,使系统管理员简单,因为它是绝对必须是可用的和可恢复所有的时间嘛。
但你仍然需要保持每个分支的一个克隆,/你需要构建和测试版本。这是微不足道的,你可以hg clone <main repo>#<branch> <branch repo>
,然后hg pull
分支回购只会拉新的变更是该分支(加祖先的变更在早期分支是被合并)。
此设置最适合的Linux内核提交单根牵拉的模型(不感觉不错表现得像莱纳斯主。在我们公司,我们称之为作用积分),作为主要的回购协议是开发者需要克隆和唯一车夫需要将其拉入。分支回购的维护纯粹是为了发布管理,并且可以完全自动化。开发人员永远需要从拉/推到分支回购。
这是@毫克的例子recasted此设置。初始点:
[a] - [b]
使一个发行版本命名分支,比方说“1.0”,当你到一个alpha版本。提交就可以了bug修复:
[a] - [b] ------------------ [m1]
\ /
(1.0) - [x] - [y]
(1.0)
是不是一个真正的变更,因为命名的分支不存在,直到你提交。 (你可以做一个简单的承诺,如添加标签,以确保命名的分支正确创建。)
合并[m1]
的关键是这个设置。不像开发商储存库,可以有头数量不受限制,你不想在你的主仓库多头(除老,死的发布分支如前所述)。所以每当你上发布分支有新的变更,必须合并他们回到立即默认分支(或更高版本分支)。这保证了一个释放任何错误修复也包含在所有更高版本。
在默认分支的同时发展向着下一个版本延续了:
------- [c] - [d]
/
[a] - [b] ------------------ [m1]
\ /
(1.0) - [x] - [y]
和往常一样,你需要在默认分支的两个头合并:
------- [c] - [d] -------
/ \
[a] - [b] ------------------ [m1] - [m2]
\ /
(1.0) - [x] - [y]
这是1.0分支克隆:
[a] - [b] - (1.0) - [x] - [y]
现在,它是一个锻炼添加下一个版本分支。如果是2.0那么它肯定会岔开默认。如果是1.1,你可以选择岔开1.0或默认。无论如何,对1.0任何新的变更应首先合并的下一个分支,然后为默认值。这可以自动如果没有冲突,导致仅仅是一个空的合并来完成。
我希望的例子让我更早分清楚。总之,这种方法的优点是:
UPDATE HG本身does this:在main repo包含默认和稳定分支,和stable repo是稳定分支的克隆。它不使用版本控制分支,不过,沿着稳定分支版本的标签是它的发行管理的目的不够好。
主要的区别,因为据我所知,是你已经指出:名为支在单个存储库中。命名分支机构所拥有的一切在一个地方派上用场。独立回购体积较小,容易走动。究其原因有两个思想流派在这是,有没有明显的赢家。不论哪一方的观点最有意义你可能是一个你应该去,因为很可能他们的环境是最相似的你。
我认为这是明显地根据当前形势,例如一个务实的决定功能/重新设计的尺寸。我想叉与还未提交者的角色与忽略的技术开销证明其资质加入开发团队贡献者真的很好。
我真的建议不要使用命名为分支版本。这真的是标签是。命名分支意味着持久改道,就像一个stable
分支。
那么为什么不直接使用标签?一个基本的例子:
这将创建在default
分支未命名的新头,又名。一个匿名的分支,它是在汞完美的罚款。然后,您可以在任何时候合并bug修正提交到主要的发展轨道。无需命名的分支。