集中式和分布式版本控制系统的比较

使用集中式和分布式版本控制系统(DVCS)有什么好处和缺点 ? 你有没有遇到DVCS的任何问题,你是如何防范这些问题的? 保持讨论工具不可知和燃烧到最低限度。

对于那些想知道什么DVCS工具可用的人来说,下面是一个最着名的免费/开源DVCS列表:

  • Git (由C语言编写)由Linux Kernel和Ruby on Rails使用 。
  • Mercurial (由Python编写)由Mozilla和OpenJDK使用 。
  • Bazaar (用Python编写)由Ubuntu开发者使用 。
  • Darcs (写在Haskell)。

从我的回答到另外一个问题 :

分布式版本控制系统(DVCS)解决了与集中式VCS不同的问题。 比较它们就像比较锤子和螺丝刀。

集中的VCS系统的devise意图是有一个真正的来源是有福的,因此是好的。 所有的开发人员都从这个源头开始工作(签出),然后添加(提交)他们的更改,这些更改同样变得有福了。 CVS,Subversion,ClearCase,Perforce,VisualSourceSafe和所有其他CVCS之间的唯一真正区别在于每个产品提供的工作stream程,性能和集成。

分布式VCS系统旨在使一个存储库与其他存储库一样好,并且从一个存储库合并到另一个存储库只是另一种通信forms。 任何仓库应该被信任的语义值都是由外部的过程而不是由软件本身强加的。

使用一种或另一种types的真正select是组织性的 – 如果您的项目或组织需要集中控制,那么DVCS是不起作用的。 如果您的开发人员需要在全国/世界各地工作,而没有安全的宽带连接到中央存储库,那么DVCS可能是您的救命稻草。 如果你需要两个,你是fsck'd。

对于那些认为分布式系统不允许权威拷贝的人来说,请注意,分布式系统有很多地方都有权威的拷贝,完美的例子大概是Linus的内核树。 肯定有很多人有自己的树,但几乎所有的人都stream向了Linus的树。

也就是说,我认为分布式SCM只对许多做不同事情的开发人员有用,但是最近决定集中式存储库可以做分布式的任何东西都可以做得更好。

例如,假设您是个人项目的独立开发人员。 集中式存储库可能是一个明显的select,但考虑这种情况。 您远离networking访问(在飞机上,在公园等),并希望在您的项目上工作。 你有你的本地副本,所以你可以做的很好,但你真的想提交,因为你已经完成了一个function,并希望移动到另一个,或者你发现一个错误修复或任何。 重点在于,通过集中式回购,您最终可以将所有更改混合在一起,并以非逻辑更改集的forms提交,也可以稍后手动将其分开。

有了分布式回购,你照常开展业务,承诺,继续,当你有networking访问,你推到你的“一个真正的回购”,没有任何改变。

更不用提关于分布式回购的其他好处:始终提供完整的历史logging。 离开networking时需要查看修订日志? 您需要注释源代码以查看如何引入错误? 所有可能的分布式回购。

请不要相信分发与集中是关于所有权或权威副本或类似的东西。 现实分布是SCM发展的下一步。

不是一个真正的比较,但是这是什么大项目使用:

集中式VCS

  • 颠覆

    Apache,GCC,Ruby,MPlayer,Zope,Plone,Xiph,FreeBSD,WebKit,…

  • CVS

    CVS

分布式VCS

  • 混帐

    Linux内核,KDE,Perl,Ruby on Rails,Android,Wine,Fedora,X.org,Mediawiki,Django,VLC,Mono,Gnome,Samba,CUPS,GnuPG,Emacs ELPA …

  • mercurial(hg)

    Mozilla和Mozdev,OpenJDK(Java),OpenSolaris,ALSA,NTFS-3G,Dovecot,MoinMoin,mutt,PETSc,Octave,FEniCS,Aptitude,Python,XEmacs,Xen,Vim,Xine …

  • BZR

    Emacs,Apt,Mailman,MySQL,Squid,…也在Ubuntu内部推广。

  • 的darcs

    ghc,ion,xmonad,…在Haskell社区中stream行。

  • 化石

    SQLite的

W. Craig Trader对DVCS和CVCS说:

如果你需要两个,你是fsck'd。

在使用两者时,我不会说你是fsck 。 实际上,使用DVCS工具的开发人员通常会尝试将其更改(或发送拉请求)与中央位置(通常发布到发布存储库中的发布分支)合并。 对于使用DVCS的开发人员来说有一些讽刺意味,但是最终使用一个中央工作stream程,您可以开始怀疑分布式方法是否真的比集中式更好。

DVCS在CVCS上有一些优势:

  • 唯一可识别的提交的概念使得无需在同伴之间发送补丁。 也就是说,您将该补丁作为提交,并与需要它的其他开发人员共享。 之后当每个人都想合并在一起时,这个特定的提交被认可,并且可以在分支之间进行比较,合并冲突的机会较小。 无论您使用哪种版本工具,开发人员都倾向于通过USB存储棒或电子邮件将补丁发送给对方。 不幸的是,在CVCS的情况下,版本控制将注册提交作为单独的,没有认识到变化是相同的,导致合并冲突的机会更大。

  • 你可以有本地实验分支(克隆仓库也可以被认为是一个分支),你不需要向其他人展示。 这意味着,如果您没有向上游推送任何信息,则不必影响开发人员。 在一个CVCS中,当你还有一个突破性的变化时,你可能不得不离线工作,直到你修复它,然后提交修改。 这种方法有效地破坏了使用版本控制作为安全网的目的,但这是CVCS中的必要罪恶。

  • 在当今世界,公司通常与离岸开发者合作(或者如果他们想更好地在家工作)。 拥有DVCS可以帮助这些项目,因为它消除了可靠的networking连接,因为每个人都有自己的回购。

…和一些通常有解决方法的缺点:

  • 谁有最新版本? 在CVCS中,干线通常有最新版本,但在DVCS中可能并不明显。 解决方法是使用行为规则,即项目中的开发人员必须达成一个协议,在这个协议中,回购合并他们的工作。

  • 悲观locking,即在签出时locking文件通常是不可能的,因为在DVCS中的存储库之间可能发生并发。 版本控制中存在文件locking的原因是因为开发人员希望避免合并冲突。 但是,由于两个开发人员不能同时使用同一块代码,所以locking具有减慢开发速度的缺点,并且不能像一个长的事务模型那样工作,也不能充分certificate合并冲突。 无论版本控制,唯一理智的方法是解决大的合并冲突,就是要有良好的代码架构(如低耦合高内聚性),并且分工您的工作任务,以便对代码的影响较小(说起来容易做起来难) 。

  • 在专有项目中,如果整个存储库公开可用,那将是灾难性的。 如果一个不满或恶意的程序员得到一个克隆的存储库,更是如此。 源代码泄露对专有业务来说是一个严重的痛苦。 由于您只需要克隆存储库,DVCS使得这一切变得简单,而一些CM系统(例如ClearCase)试图限制该存取。 然而,在我看来,如果您的公司文化中有足够的function障碍,那么世界上没有版本控制可以帮助您防止源代码泄露。

在我search正确的SCM期间,我发现以下链接非常有帮助:

  1. 更好的SCM计划:比较 。 比较大约26个版本控制系统。
  2. 修订控制软件的比较 。 维基百科的文章比较了38个版本控制系统,涵盖了技术差异,function,用户界面等主题。
  3. 分布式版本控制系统 。 另一个比较,但主要集中在分布式系统。

这两个scheme在一定程度上是等价的:

  • 如果在每次本地提交之后,只是始终将更改推送到某个指定的上游存储库,则分布式VCS可以轻而易举地模拟一个集中的VCS。
  • 一个集中的VCS通常不会像自然一样模仿一个分布式的VCS,但是如果你在上面使用诸如quilt之类的东西,你可以得到非常相似的东西。 被子,如果你不熟悉的话,是一个在上游项目之上pipe理大量补丁的工具。 这里的想法是通过创build一个新的补丁来实现DVCS commit命令,并且通过向集中式VCS提交每个未完成的补丁然后丢弃补丁文件来实现push命令。 这听起来有些尴尬,但实际上它实际上工作得很好。

话虽如此,DVCS传统上做得非常好,而且大多数中央VCS都做了一些散列。 其中最重要的可能是分支:一个DVCS将使得分支仓库或者合并不再需要的分支变得非常容易,并且当你这样做的时候会logging历史。 中央计划为什么会遇到这个问题没有什么特别的理由,但是从历史上看似乎没有什么不对的。 这对你来说是否是一个问题取决于你如何组织开发,但是对很多人来说这是一个重要的考虑因素。

DVCSes的另一个优点是它们可以离线工作。 我从来没有真正用过这个东西。 我主要是在办公室(所以在本地networking的存储库)或在家里(所以有ADSL)进行开发。 如果你在旅行的时候在笔记本电脑上做了很多的开发,那么这对你来说可能更值得考虑。

实际上并没有很多特定于DVCS的问题。 人们有一个稍微大一点的安静的倾向,因为你可以毫不动摇地承诺,很容易就可以私下抛光,但除此之外我们还没有很多问题。 这可能是因为我们有相当数量的开源开发人员,他们通常熟悉开发的补丁交易模式,但是进入的闭源开发人员似乎也很快就能find合适的东西。

分布式VCS在很多方面都有吸引力,但是对我公司来说非常重要的一个缺点是pipe理非可合并文件(通常是二进制文件,例如Excel文档)的问题。 Subversion通过支持“svn:needs-lock”属性来处理这个问题,这意味着在编辑它之前,你必须获得非可合并文件的locking。 它运作良好。 但是,这种工作stream程需要一个集中的存储库模型,这与DVCS概念相反。

所以如果你想使用DVCS,那么pipe理不可合并的文件是不合适的。

我已经使用颠覆多年了,我真的很高兴。

然后GIT的嗡嗡声开始了,我只需要testing它。 对我来说,主要卖点是分支。 好家伙。 现在我不再需要清理我的存储库,回到几个版本或者使用subversion时做的任何愚蠢的事情。 在dvcs中一切都很便宜。 我只尝试过化石和git,但是我使用过perforce,cvs和subversion,看起来dvcs都有非常便宜的分支和标记。 不再需要将所有代码复制到一边,因此合并只是一件轻而易举的事情。

任何dvcs都可以使用中央服务器进行设置,但是除此之外,

你可以检查你喜欢的任何小小的变化,就像Linus说的,如果你需要使用多个句子来描述你刚刚做了什么,那么你做的太多了。 你可以在代码,分支,合并,克隆和testing所有本地的方式,而不会导致任何人下载大量的数据。 你只需要把最后的改变推送到中央服务器。

你可以在没有networking的情况下工作。

所以总之,使用版本控制总是一件好事。 使用dvcs更便宜(KB和带宽),我觉得使用起来更有趣。

结帐Git: http : //git-scm.com/
结帐Fossil: http : //www.fossil-scm.org
结帐Mercurial: https : //www.mercurial-scm.org

现在,我只能推荐dvcs系统,并且您可以轻松地使用中央服务器

主要问题(除了明显的带宽问题)是所有权

这是为了确保不同的(地理)网站不在同一个元素上工作。

理想情况下,该工具可以将所有权分配给文件,分支甚至存储库。

为了回答这个答案的意见,你真的希望这个工具告诉你谁拥有什么, 然后通过电话,IM或邮件与远方的网站进行交stream。
如果你没有所有权机制,你将会“沟通”,但往往来不及;)(即:在同一分支的同一组文件上完成并发开发之后,提交可能会变得混乱)

对我来说,这是另外一个关于个人品味的讨论,要真正客观,是相当困难的。 我个人比其他DVCS更喜欢Mercurial 。 我喜欢用与Mercurial相同的语言编写钩子,而且networking开销较小,这只是为了说明一些我自己的原因。

现在每个人都在谈论DVCS如何优越,但克雷格的评论是重要的。 在DVCS中,每个人都有分支的全部历史。 如果您正在处理大量的二进制文件(例如图像文件或FLA),则需要大量的空间,您无法进行差异化处理。

我有一种感觉,Mercurial(和其他DVCS)比集中式的更复杂。 例如,在Mercurial中合并一个分支会保留分支的完整历史logging,而在SVN中,您必须转到分支目录来查看历史logging。

即使在独立开发者的情况下,分布式供应链pipe理的另外一个优点是,如果你像我们当中的许多人一样,有多台机器在工作。

比方说你有一套共同的脚本。 如果你工作的每台机器都有一个克隆,你可以根据需要更新并更改你的脚本。 它给你:

  1. 节省时间,尤其是使用ssh密钥
  2. 一种分歧不同系统之间差异的方式(例如Red Hat vs Debian,BSD vs Linux等)

克雷格交易者的答案总结了大部分,但是,我发现个人的工作风格也有很大的不同。 在我目前工作的地方,我们使用Subversion作为我们的One True Source,然而,许多开发人员在他们的个人计算机上使用git-svn来弥补我们的工作stream程问题(pipe理失败,但这是另一回事)。 任何状况之下。 它的真正目的是平衡哪些function集使您的组织效率最高(例如集中authentication)。

集中式系统不一定会阻止您使用独立的分支机构进行开发。 不需要成为代码库的单一副本,而不同的开发者或团队可以有不同的分支,遗留分支可以存在等等。

它通常意味着存储库是集中pipe理的 – 但是这对于拥有一个有能力的IT部门的公司来说通常是一个优势,因为这意味着只有一个地方可以备份,只有一个地方可以pipe理存储。