在大型组织中使用Mercurial

63

我已经在我的个人项目中使用Mercurial一段时间了,而且我很喜欢它。我的雇主正在考虑从CVS切换到SVN,但我想知道是否应该推动改用Mercurial(或其他DVCS)。

Mercurial的一个问题是它似乎是围绕着每个“项目”只有单个存储库的想法设计的。 在这个组织中,当前的CVS存储库中有许多不同的可执行文件、DLL和其他组件,按层次结构组织。 有很多通用的可重用组件,但也有一些客户特定的组件和客户特定的配置。 目前的构建过程通常会从CVS存储库中获取某些子树集。

如果我们从CVS迁移到Mercurial,最佳的存储库/存储库组织方式是什么? 我们应该有一个包含所有内容的巨大的Mercurial存储库吗? 如果不是,较小的存储库应该有多精细? 我认为,如果他们必须从很多不同的地方拉取和推送更新,人们会觉得非常烦人,但如果他们必须拉/推整个公司的代码库,他们也会感到烦恼。

有没有人有经验或建议?


相关问题:

3个回答

55

声明:这是从另一个关于Git的线程中转贴过来的,但我还是推荐Mercurial。它涉及企业上下文中的分布式版本控制系统,因此我希望跨越贴文可以接受。我稍微修改了一下,以更好地适应这个问题:


与普遍意见相反,我认为在企业环境中使用分布式版本控制系统是一个理想的选择,因为它可以实现非常灵活的工作流程。首先,我将谈论使用DVCS vs. CVCS的区别,然后介绍最佳实践,最后讨论关于Git。

企业环境下的DVCS vs. CVCS:

我不会在这里讨论一般的优缺点,而是关注您的具体情况。通常认为,在企业环境中使用DVCS需要比使用集中式系统更加有纪律的团队。这是因为集中式系统提供了一种简单的方法来“强制执行”您的工作流程,而使用分布式系统需要更多的沟通和纪律来坚持已经建立的惯例。虽然这可能看起来增加了额外的开销,但是我认为增加的沟通对于使其成为良好的过程是有益的。您的团队将需要就代码、变更以及项目状态进行沟通。

另一个纪律方面的维度是鼓励分支和实验。以下是Martin Fowlers最近在版本控制工具中发表的一句话,他为这种现象找到了一个非常简洁的描述。

DVCS鼓励快速分支进行试验。在Subversion中可以进行分支,但是它们对所有人都可见的事实会阻止人们开展试验性工作。同样,DVCS鼓励对工作进行检查点:将不完整的更改提交到本地存储库,这些更改甚至可能无法编译或通过测试。在Subversion的开发者分支上也可以这样做,但是这种分支在共享空间中使人们不太可能这样做。
DVCS通过有向无环图(DAG)中的全局唯一标识符提供变更集跟踪,而不是简单的文本差异,从而使其能够透明地跟踪变更集的起源和历史,这可能非常重要。
工作流程:
Larry Osterman(Windows团队的微软开发人员)在他的博客文章中介绍了他们在Windows团队中采用的工作流程。其中最值得注意的是:
- 干净、高质量的代码仅存储在主干(主存储库)中 - 所有开发都在功能分支上进行 - 功能团队拥有团队存储库 - 定期将最新的主干更改合并到其功能分支中(前向集成) - 完整的功能必须通过几个质量门(例如审核、测试覆盖率、Q&A)(各自的存储库) - 如果功能完成且质量可接受,则将其合并到主干中(反向集成)
如您所见,让每个仓库独立存在可以使不同团队以不同的速度推进而解耦。另外,实现灵活的质量门控系统的可能性使得分布式版本控制系统(DVCS)与集中式版本控制系统(CVCS)有所区别。您也可以在这个层面上解决您的权限问题。只有少数人应该被允许访问主仓库。对于层次结构的每个级别,都要有一个单独的仓库和相应的访问策略。事实上,这种方法在团队层面上非常灵活。您应该让每个团队自行决定是否想要共享他们的团队仓库,还是希望采用更加等级化的方法,只有团队领导才能提交到团队仓库。

Hierachical Repositories

(这张图片是从Joel Spolsky的hginit.com中偷来的。)

在这一点上还有一件事情需要说,即使DVCS提供了很好的合并功能,这绝不是使用持续集成的替代品。即使在那个时候,你也有很大的灵活性:对于主干存储库,团队存储库,Q&A存储库等都可以使用CI。

企业环境中的Mercurial:

我不想在这里引发git vs. hg的争论,你已经考虑切换到DVCS了,这是正确的方向。以下是选择使用Mercurial而不是git的几个原因:

  • 支持运行python的所有平台
  • 在所有主要平台(win/linux/OS X)上有出色的GUI工具,第一流的合并/vdiff工具集成
  • 非常一致的界面,对svn用户易于过渡
  • 可以做到与git大部分相同的事情,但提供了更清晰的抽象。危险操作总是明确的。高级功能通过必须显式启用的扩展提供。
  • 来自selenic的商业支持

简而言之,在企业中使用DVCS时,我认为选择引入最少摩擦的工具非常重要。为了使过渡成功,特别需要考虑开发人员之间(关于VCS)的不同技能。

最后我想指出一些资源。Joel Spolsky 最近写了一篇论文,驳斥了很多反对 DVCS 的观点。必须提到其他人在很久以前就发现了这些反对观点。另一个好的资源是 Eric Sink 的博客,在那里他写了一篇关于企业 DVCS 面临的障碍的文章。


43
据我所知,大多数人对任何分布式版本控制系统的抵制都来自于他们不了解如何使用它们。经常重复的说法“没有中央仓库”对那些一直被锁定在CVS/SVN模型下并且无法想象其他方式的人来说是非常可怕的,尤其是对于管理层和高级(有经验和/或愤世嫉俗的)开发人员来说,他们希望有强大的源代码跟踪和可重现性(也许还需要满足某些关于开发流程的标准,就像我曾经工作过的地方一样)。好吧,你可以拥有一个中央“神圣”的仓库;你只是没有被束缚在它上面。例如,子团队很容易在他们的工作站之一上建立一个内部游乐场仓库。
有很多方法可以完成同样的事情,因此请认真考虑您的工作流程。考虑您当前的实践以及近乎免费的克隆和分支提供的功能。您当前做的一些事情可能已经演变成为解决CVS类型模型的限制而设计的;您需要准备打破这种模式。您可能需要指定一两个负责人来帮助大家过渡;对于一个大团队,您可能需要考虑限制提交访问权限。
在我的工作中(小型软件公司),我们从CVS转移到了hg,不会再返回。我们主要使用集中式的方式。将我们的主代码库(古老且非常庞大)转换是困难的,但无论如何都是这样的,完成后就完成了 - 更改版本控制系统将变得更容易。(我们发现有许多情况,CVS转换工具只是无法弄清楚发生了什么;某人的提交仅部分成功并且他们几天内没有注意到;解决供应商分支;由时间倒流引起的普遍疯狂和疯狂,由于来自不同时区的本地时间的提交时间戳而没有帮助...)
我发现DVCS的巨大好处是能够早期提交,经常提交,并且仅在准备就绪时推送。当我达到各种进行中的里程碑时,我喜欢立下一个界限,以便如果需要,我可以回到某个位置 - 但这些提交不应该暴露给团队,因为它们在很多方面都不完整。(我主要使用mercurial queues完成这项操作。)这一切都与工作流程有关;我永远无法在CVS中做到这一点。
我想你已经知道了,但是如果你正在考虑摆脱CVS,你可以做得比SVN更好...
要选择单块式还是模块化的方式?无论你使用分布式还是非分布式版本控制系统,任何范式转换都将变得棘手;CVS模型在允许你按文件提交而不检查存储库的其余部分是否已经更新方面是相当特殊的(别提模块别名可能会引起的头疼了)。
处理单块式存储库可能会非常缓慢。与仅针对单个模块相比,你的vcs客户端必须扫描整个宇宙的副本以查找变更(如果你正在Linux上工作,请查看hg inotify扩展,如果你还没有这样做)。
单块式存储库还会在提交(推送)时导致不必要的竞争条件。它就像CVS的最新检查一样,但应用于整个存储库:如果你有很多活跃的开发人员,频繁提交,这个问题会困扰你。
我建议值得努力远离单块式,但请注意,它将在构建系统中增加复杂性。 (附注:如果你发现某些事情很烦人,请自动化它!我们程序员毕竟是懒惰的生物。)将存储库拆分为所有组件模块可能过于极端;可能会在少数存储库中将相关组件分组。你还可以查看mercurial的子模块支持-Nested RepositoriesForest Extension(我应该尝试理解它们)。
在以前的工作场所,我们有几十个组件,这些组件被保留为独立的CVS模块,并具有相当规范的元结构。组件声明了它们依赖的内容以及应该将哪些构建部分导出到哪里;构建系统会自动编写make片段,以便你正在处理的内容可以获取所需的内容。它通常运行得非常好,很少会失败CVS最新检查。(还有一个非常复杂但极其强大的构建机器人,对于依赖关系分辨率的最小努力态度:如果已经有满足您要求的组件,则不会重新构建组件。加上元组件,可以组装安装程序和整个ISO镜像,这是一个易于开始和完成构建的好方法,也是事情变得像巫师一样的好方法。应该有人写一本书...)

8

首先,最近关于在大型项目中使用DVCS的讨论是相关的:

分布式版本控制在巨大项目中是否可行?

Mercurial的一个问题是它似乎是围绕着每个“项目”拥有单个仓库的想法设计的。

是的,虽然Subversion的规范是在一个单一的仓库中包含多个项目,但使用DVCS最好拥有更精细的仓库,每个组件一个。Subversion有svn:externals功能,在检出时聚合多个源树(这有其自身的后勤和技术问题)。Mercurial和Git都有类似的功能,称为子仓库

子仓库的想法是您对于每个组件都有一个仓库,并且可发布的产品(由多个可重用组件组成)将简单地引用其依赖仓库。当您克隆产品仓库时,它会带上所需的组件。

我们是否应该拥有一个包含所有内容的巨大Mercurial存储库?如果不是,较小的存储库应该有多细粒度?我认为如果人们必须从许多不同的地方拉取和推送更新,他们会发现这非常烦人,但如果他们必须拉/推整个公司代码库,他们也会感到烦恼。
当然可以拥有一个单块的存储库(如果需要,甚至可以在下一步将其拆分)。使用此方法的问题更可能涉及发布时间表以及如何管理不同组件的不同版本。如果您有多个具有自己发布时间表的产品共享公共组件,则最好采用更细粒度的方法,以促进配置管理。
一个警告是,子存储库支持是相对较新的功能,并且不像其他功能那样完全成熟。具体而言,并非所有hg命令都知道子存储库,尽管最重要的命令都知道。
我建议您执行测试转换,并尝试使用子存储库支持,组织产品和相关组件等。我正在进行同样的事情,这似乎是正确的方式。

我强烈支持测试转换。一如既往,这取决于您的管理层如何看待那些表面上看起来并不“有生产力”的工作... - crazyscot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接