在大型组织中使用Mercurial

我一直在为自己的个人项目使用Mercurial,我喜欢它。 我的雇主正在考虑从CVS切换到SVN,但我想知道是否应该推动Mercurial(或其他DVCS)。

Mercurial的一个问题是它似乎是围绕着为每个“项目”设置一个存储库的想法来devise的。 在这个组织中,当前CVS存储库中有许多不同的可执行文件,DLL和其他组件,分层组织。 有很多通用的可重用组件,还有一些客户特定的组件,以及客户特定的configuration。 当前的构build过程通常从CVS存储库中获取一些子树。

如果我们从CVS转到Mercurial,组织仓库/仓库的最好方法是什么? 我们应该有一个巨大的Mercurial存储库包含一切吗? 如果不是,那么较小的存储库应该如何细化? 我认为人们会发现,如果他们不得不从很多不同的地方进行更新,他们会觉得非常烦恼,但是如果他们不得不推拉整个公司的代码库,他们也会觉得很烦。

任何人都有这方面的经验,或build议?


相关问题:

  • 企业中基于Git的源代码pipe理:build议的工具和实践?
  • 巨大项目的分布式版本控制 – 是否可行?

AFAICS对于任何DVCS的阻力大部分来自不明白如何使用它们的人。 对于自古以来一直被locking在CVS / SVN模型中的人们来说,“没有中央存储库”这个经常被重复的陈述是非常可怕的,而且无法想像其他什么,特别是对于pipe理层和高级(有经验的和/或玩世不恭的)开发人员,他们需要强大的源代码跟踪和可重复性(也许还需要满足某些关于开发stream程的标准,就像我们曾经工作过的地方一样)。 那么,你可以有一个中央“有福”的回购; 你只是没有镣铐到它。 例如,一个小组在一个工作站上设置一个内部操场回购很容易。

有这么多的方式来剥皮的谚语猫,它会支付你坐下来仔细思考你的工作stream程。 想想你现在的做法和近乎免费的克隆和分支给你的力量。 你目前所做的一些工作可能会演变为解决CVStypes模型的局限性; 准备打破模具。 你可能需要任命一个或两个冠军来缓解每个人的转型。 与一个大团队,你可能想考虑限制提交访问有福

在我的工作(小软件公司),我们从CVS移动到HG,不会回去。 我们以大多数集中的方式使用它。 转换我们的主要(古老的和非常大的)回购是痛苦的,但它会是你走的任何方式,当它完成时 – 它会稍后改变VCS更容易。 (我们发现了一些CVS转换工具无法弄清楚发生了什么的情况;某些人的提交只取得了部分成功,并且他们没有注意到几天;解决了供应商分支问题;由于时间的推移而导致的疯狂和疯狂倒退,没有在当地时间从不同的时区提交时间戳帮助…)

我发现DVCS带来的巨大好处是能够提前做出承诺,并且在做好准备后才能进行提交。 当我达到各种进行中的里程碑时,我喜欢在沙滩上划一条线,这样我就可以回到某个地方,如果需要的话 – 但这些不是应该暴露给团队的提交,因为它们明显不完整以无数的方式。 (我主要是通过mercurial queues来做这件事情)。 我不可能用CVS做到这一点。

我猜你已经知道了,但是如果你正在考虑离开CVS,你可以做得比SVN好多了…


巨石,还是模块? 无论您使用的是VCS还是分布式,任何范式转变都会变得棘手。 CVS模型是非常特殊的,它允许你逐个文件地提交文件,而不检查其他的回购是否是最新的(我们不要提到模块别名已经引起的头痛)。

  • 处理整体存储库可能会非常缓慢。 您的vcs客户端必须扫描您的整个Universe的副本才能进行更改,而不仅仅是一个模块。 (如果您正在使用Linux,请查看hg inotify扩展,如果您还没有这样做。)
  • 一个单一的回购也造成不必要的竞争条件时(推)。 这就像CVS最新的检查,但应用于整个回购:如果你有许多活跃的开发人员,经常犯,这个会咬你。

我build议,远离单片机是值得的,但是要注意,它会在构build系统中增加复杂性方面带来自己的开销。 (注意:如果你发现一些烦人的事情,那就自动化吧!毕竟,我们的程序员是懒惰的生物。)把你的repo分解到所有的组件模块中可能太过分了。 可能会有一个中途的房子被发现与相关的组成部分在less数几个知识库之间。 你也可能会发现,看看mercurial的子模块支持 – 嵌套仓库和森林扩展 (这两个我应该试图让我的头)是有用的。

在以前的工作场所,我们有几十个组件,这些组件被保持为独立的CVS模块,具有相当规整的元结构。 组件声明他们依赖和哪些构build的部分将被出口的地方; 构build系统会自动写入make fragment,以便您正在处理的内容能够提取所需内容。 它通常工作得很好,CVS最新检查失败的情况非常罕见。 (还有一个非常复杂但function非常强大的构build机器人,对解决依赖问题的态度是最小的:如果已经有一个满足你的需求的组件,它就不会重build一个组件。 ISO的图像,你有一个很好的配方,从开始到结束的简单构build,以及巫师学徒的事情。有人应该写一本关于它的书…)

披露:这是一个来自另一个围绕git的线程的交叉post ,但我最终推荐了mercurial。 它一般在企业环境中处理DVCS,所以我希望交叉发布是好的。 我已经修改了一下,以更好地适应这个问题:


根据共同意见,我认为使用DVCS是企业设置的理想select,因为它可以实现非常灵活的工作stream程。 我将首先讨论使用DVCS与CVCS,最佳做法,然后讨论git。

企业上下文中的DVCS vs. CVCS:

我不会谈论这里的一般优点/缺点,而是侧重于你的背景。 普遍认为,使用DVCS需要比使用集中式系统更有纪律的团队。 这是因为中央系统为您提供了一个简单的方法来执行您的工作stream程,使用分散的系统需要更多的沟通和纪律来坚持已build立的惯例。 虽然这看起来似乎导致了开销,但我认为增加沟通对于使其成为一个好的过程是必要的。 一般来说,您的团队需要就代码,变更和项目状态进行沟通。

纪律的另一个方面是鼓励分支和实验。 以下是Martin Fowlers最近在版本控制工具中提供的 bliki条目的一个引用,他发现了这个现象的一个非常简洁的描述。

DVCS鼓励快速分支实验。 你可以在Subversion中做分支,但是它们对所有人都是可见的,这就阻碍了人们开放实验工作的分支。 同样,DVCS鼓励检查工作:将不完整的更改提交给本地存储库,甚至不会编译或通过testing。 你也可以在Subversion的开发者分支上这样做,但是这样的分支在共享空间中的事实使得人们不太可能这样做。

DVCS支持灵活的工作stream程,因为它们通过有向无环图(DAG)中的全局唯一标识符提供变更集跟踪,而不是简单的文本差异。 这使得他们能够透明地追踪变更集的起源和历史,这一点非常重要。

工作stream程:

Larry Osterman(一位在Windows团队工作的微软开发人员)有一篇关于他们在Windows团队中使用的工作stream程的博文 。 最值得注意的是他们有:

  • 干净,高品质的代码只有主干(主回购)
  • 所有的开发发生在function分支上
  • 特征团队有团队回购
  • 他们经常将最新的主干更改合并到他们的function分支( Forward Integrate
  • 完整的function必须通过几个质量大门,如审查,testing覆盖面,问答(自己的回购)
  • 如果某个function已经完成并且具有可接受的质量,则会合并到主干中( Reverse Integrate

正如你所看到的,让这些仓库中的每一个都可以独立运作,你可以将不同的队伍分成不同的队伍。 此外,实施灵活的质量门系统的可能性区分DVCS和CVCS。 您也可以在这个级别解决您的权限问题。 只有less数人可以进入主回购。 对于层次的每个级别,有相应的访问策略单独的回购。 事实上,这种方法在团队层面上可以非常灵活。 你应该让每个团队决定是否要在他们之间分享他们的团队回购,或者如果他们想要一个更强硬的方法,只有团队领导可以承诺团队回购。

分级存储库

(这张照片是从Joel Spolsky的hginit.com偷来的)

在这一点上还有一点要说,即使DVCS提供了很好的合并能力,但这永远不能替代使用连续集成。 即使在那个时候,你也有很大的灵活性:主干回购CI,团队回购CI,问答回购等。

Mercurial在企业背景下:

我不想在这里启动git vs. hg flamewar,考虑切换到DVCS,您已经走上了正轨。 这里有几个使用Mercurial而不是git的原因:

  • 所有运行python的平台都被支持
  • 在所有主要平台(win / linux / OS X),头等的合并/ vdiff工具集成上都有很棒的GUI工具
  • 非常一致的界面,为svn用户轻松过渡
  • git也可以做大部分的事情,但是提供了一个更清晰的抽象。 危险的行动总是明确的。 高级function通过必须明确启用的扩展来提供。
  • 商业支持来自于亚selenium酸盐。

总之,在企业中使用DVCS时,我认为select一种引入最less摩擦的工具是很重要的。 为了成功转型,考虑开发者之间的不同技能(关于VCS)尤为重要。

最后我想指出一些资源。 Joel Spolsky最近写了一篇文章,打败了许多针对DVCS提出的论点。 必须提到的是,早就有人发现了这些矛盾。 另一个很好的资源是Eric Sinks博客,他在那里写了一篇关于企业DVCS障碍的文章。

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

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

Mercurial的一个问题是它似乎是围绕着为每个“项目”设置一个存储库的想法来devise的。

是的,虽然Subversion的规范是有一个包含多个项目的整体存储库,但对于DVCS,最好有更多的粒度存储库(每个组件一个)。 Subversion具有svn:externals特性,可以在结帐时聚合多个源代码树(它有自己的逻辑和技术问题)。 Mercurial和Git都有类似的function,在hg中称为subrepos 。

subrepos的想法是每个组件有一个回购,而一个可释放的产品(包含多个可重用的组件)将简单地引用其依赖的回购。 当您克隆产品回购时,它会带来所需的组件。

我们应该有一个巨大的Mercurial存储库包含一切吗? 如果不是,那么较小的存储库应该如何细化? 我认为人们会发现,如果他们不得不从很多不同的地方进行更新,他们会觉得非常烦恼,但是如果他们不得不推拉整个公司的代码库,他们也会觉得很烦。

当然也可以有一个单一的仓库(如果需要的话,你甚至可以把它分解到轨道上)。 这种方法的问题更可能归结为发布schedles,以及如何pipe理不同版本的不同组件。 如果您有多个产品具有共享通用组件的自己的发布计划,那么使用更细化的方法可能会更好,以促进configurationpipe理。

一个警告是,次级支持是一个相对较新的function,并不像其他function完全成熟。 具体来说,并不是所有的hg命令都知道subrepos,尽pipe最重要的命令是。

我build议你进行一个testing转换,然后试验一下subrepo支持,组织产品和依赖组件等。我正在做同样的事情,这似乎是要走的路。