it-swarm.cn

我是Subversion极客,为什么我应该考虑或不考虑Mercurial或Git或任何其他DVCS?

我试图了解分布式版本控制系统(DVCS)的好处。

我发现 Martin FowlerSubversion再教育本文 非常有用。

Mercurial和其他DVCS促进了使用变更集和本地提交的新代码处理方式。它防止合并地狱和其他协作问题

在我练习 连续集成 时,我们不受此影响,除非在进行实验,否则不能在私有分支中单独工作。我们为每个主要版本使用一个分支,其中修复了从主干合并的错误。

水星让你有中尉

我知道这对于像Linux这样的大型项目很有用,但是我看不到小型且高度协作的团队(5至7人)的价值。

Mercurial更快,占用磁盘空间更少,完整的本地副本允许更快的日志和差异操作。

我也不对此担心,因为即使我正在处理非常大的项目,我也没有注意到SVN的速度或空间问题。

我正在寻找您的个人经验和/或前SVN怪才的意见。特别是关于变更集的概念和整体绩效的提升。

更新(1月12日):我现在认为值得尝试。

更新(6月12日):我亲吻了Mercurial并且喜欢它。他的樱桃当地风味的味道。我亲吻Mercurial只是为了尝试。我希望我的SVN服务器不要介意。感觉很不对劲。感觉很好。 并不是说我今晚恋爱了.

最终更新(7月29日):我荣幸地复习了 Eric Sink 的下一本书 版本通过示例进行控制 。他说服了我。我去Mercurial。

304
user2567

注意:请参阅“编辑”以获取当前问题的答案


首先,阅读Joel Spolsky的 Subversion Re-education 。我想您的大部分问题都会在那得到解答。

另一个建议是Linus Torvalds关于Git的演讲: http://www.youtube.com/watch?v=4XpnKHJAok8 。另一个可能还会回答您的大多数问题,这很有趣。

顺便说一句,我觉得很有趣:甚至Subversion的两位原始创造者Brian Fitzpatrick和Ben Collins-Sussman在一次Google演讲中都表示“对此感到抱歉”,指的是Subversion不如Mercurial(和DVCS)。

现在,IMO和总体而言,任何DVCS的团队动态发展都更加自然,而一个显着的好处是您可以脱机提交,因为这意味着以下几点:

  • 您不依赖服务器和连接,这意味着速度更快。
  • 不要成为可以进行互联网访问(或VPN)的地方的奴隶。
  • 每个人都备份了所有内容(文件,历史记录),而不仅仅是服务器。 意味着任何人都可以成为服务器
  • 如果您需要而不弄乱别人的代码,则可以强制执行。提交是本地的。提交时不要踩到对方的脚趾。您不会仅仅通过提交来破坏他人的构建或环境。
  • 没有“提交访问权限”的人可以提交(因为在DVCS中提交并不意味着上载代码),降低了贡献的壁垒,您可以决定是否进行更改或不作为集成者。
  • 由于DVCS使得这一点至关重要,因此它可以加强自然交流。在Subversion中,您所拥有的是提交竞赛,它迫使交流,但是却阻碍了您的工作。
  • 贡献者可以组队并处理自己的合并,这最终减少了集成者的工作。
  • 贡献者可以拥有自己的分支机构,而不会影响他人的分支机构(但可以在必要时共享它们)。

关于您的观点:

  • DVCSland中不存在合并地狱;不需要处理。 请参阅下一点
  • 在DVCS中,每个人都代表一个“分支”,这意味着每当更改被拉时,就会存在合并。命名分支是另一回事。
  • 如果需要,您可以继续使用持续集成。但是不是必需的恕我直言,为什么要增加复杂性呢?只需将测试作为您的文化/政策的一部分。
  • 在某些方面,Mercurial更快,而在其他方面,git则更快。一般而言,并不是真正取决于DVCS,而是取决于它们的特定实现AFAIK。
  • 每个人都将拥有完整的项目,而不仅仅是您自己。分布式事物与您可以在本地提交/更新,从计算机外部共享/获取有关,这称为推/拉。
  • 再次,阅读Subversion再教育。 DVCS更简单,更自然,但是它们有所不同,请不要以为cvs/svn ===所有版本控制的基础。

我正在为Joomla项目提供一些文档,以帮助宣讲向DVCS的迁移,以及(-这里我制作了一些图表来说明集中式与分布式。

集中

alt text

在一般实践中分发

alt text

分配到最大

alt text

您在图中看到仍然有一个“集中式存储库”,这是集中式版本控制爱好者最喜欢的参数之一:“您仍在集中化”,不是,不是,因为“集中式”存储库只是您自己的存储库所有人都同意(例如,官方的github回购协议),但这可以随时更改。

现在,这是使用DVCS的开源项目(例如,具有大规模协作的项目)的典型工作流程:

alt text

Bitbucket.org 相当于Mercurial的github等效项,知道它们有无限的私有存储库,具有无限的空间,如果您的团队小于五个,则可以免费使用。

确信使用DVCS的最佳方法是尝试DVCS,每位使用svn/cvs的资深DVCS开发人员都会告诉您这是值得的,并且他们不知道如果没有它,他们将如何生存下来。


[〜#〜]编辑[〜#〜]:要回答您的第二次编辑,我只想重申一下,使用DVCS时您有不同的工作流程,建议您不要因为最佳实践而寻找不尝试的理由,这就像人们争论OOP不必要,因为他们可以绕开复杂的设计模式以及XYZ范式所能做的一切;无论如何您都可以受益。

尝试一下,您将看到在“私有分支”中进行工作实际上是一个更好的选择。我可以说出最后一个为什么成立的原因之一是因为您害怕提交,因此您可以在认为合适和工作的任何时候进行提交一种更自然的方式。

关于“合并地狱”,您说“除非我们正在尝试”,否则我说“即使您正在尝试+维护+ 同时在经过改进的v2.0中工作 “。正如我之前所说,合并地狱不存在,因为:

  • 每次提交时,都会生成一个未命名的分支,并且每次更改遇到其他人的更改时,都会自然合并。
  • 因为DVCS为每次提交收集更多的元数据,所以在合并过程中发生的冲突较少……因此您甚至可以将其称为“智能合并”。
  • 当您遇到合并冲突时,可以使用以下方法:

alt text

而且,项目规模也无关紧要,当我从Subversion切换时,我实际上已经在单独工作时已经看到了好处,一切都感觉不错。 变更集(不完全是修订,而是包含提交的特定文件的一组特定更改,与代码库的状态隔离开)通过对一组特定的文件(而不是整个代码库)执行的操作,可以准确地看到您的意思。

关于变更集的工作方式和性能提升。我将尝试通过一个示例来说明这一点:mootools项目从 github网络图 中所示的svn切换。

之前

alt text

之后

alt text

您所看到的是,开发人员能够在提交时专注于自己的工作,而不必担心破坏别人的代码,他们担心在推/拉之后会破坏别人的代码(DVCS:先提交,然后再推/拉,然后更新),但由于此处的合并比较聪明,因此它们通常永远不会做...即使发生合并冲突(这种情况很少见),您也只花了5分钟或更短的时间就解决了。

我对您的建议是寻找一个知道如何使用Mercurial/git的人,并告诉他/她亲自向您解释。通过在命令行中与一些朋友花费大约半小时,同时在我们的台式机和Bitbucket帐户上使用Mercurial,向他们展示了如何合并,甚至为他们捏造了冲突,以了解如何在可笑的大量时间内解决问题,它们是DVCS的真正力量。

最后,如果您与Windows人员一起工作,我建议您使用Mercurial + bitbucket而不是git + github。 Mercurial一点也更简单,但是git对于更复杂的存储库管理(例如 git rebase )更强大。

一些其他推荐的读物:

333
dukeofgaming

您要说的是,如果您实质上停留在单个分支上,则不需要分布式版本控制。

是的,但这不是对您的工作方式的不必要的强力限制,并且不能很好地扩展到多个时区中的多个位置吗?中央Subversion服务器应位于何处,并且如果该服务器由于某种原因关闭,每个人都应该回家吗?

DVCS属于Subversion,Bittorrent属于ftp

(从技术上讲,不是合法的)。也许,如果您考虑了一下,您可能会明白为什么会有这么大的飞跃?

对我来说,我们切换到git,立即导致

  • 我们的备份更容易做到(只需“ git remote update”就可以完成)
  • 在不访问中央存储库的情况下,更易于执行小的步骤。您只需工作,然后在回到托管中央存储库的网络时进行同步。
  • 更快的哈德逊建立。使用git pull比更新快得多。

因此,考虑一下为什么bittorrent比ftp更好,然后重新考虑您的位置:)


注意:已经提到在某些情况下ftp比bittorrent更快。这与您喜欢的编辑器维护的备份文件比版本控制系统使用起来更快的方式相同。

59
user1249

分布式版本控制系统的杀手级功能是分布式部分。您无需从存储库签出“工作副本”,而是克隆存储库的整个副本。这是巨大的,因为它提供了强大的好处:

  • 您可以享受版本控制的好处,即使您没有互联网访问权限,例如... 不幸的是,由于DVCS出色,它被过度使用和夸大了-它并不是一个强大的卖点,因为我们中的许多人发现自己编写的代码没有互联网访问的频率就开始下雨了。

  • 拥有本地存储库是杀手real的真正原因是在将提交历史记录推送到主存储库之前,您可以完全控制提交历史记录

曾经修复过一个错误,并最终得到如下结果:

r321 Fixed annoying bug.
r322 Argh, unexpected corner case to annoying bug in r321!
r323 Ok, really fixed corner case in r322
r324 Oops, forgot to remove some debugging code related to r321
...

等等。这样的历史是很混乱的-确实只有一个修复程序,但是现在实现是在许多包含不想要的工件的提交之间进行扩展的,例如添加和删除调试语句。对于类似SVN的系统,替代方法是不提交(!!!),直到一切正常,以保持历史记录干净。即便如此,当大量的工作没有受到版本控制的保护时,错误也会遗漏,墨菲定律正等着残酷地对待您。

拥有您自己的存储库的本地克隆,可以解决此问题,因为您可以通过连续滚动“ fix it”和“ oops”来重写历史记录”提交到“错误修复”提交中。一天结束时,一个干净的提交将发送到主存储库,如下所示:

r321 Fixed annoying bug.

应该是这样。

当与分支模型结合使用时,重写历史记录的功能将更加强大。开发人员可以执行完全独立于分支机构的工作,然后当需要将该分支机构引入主干时,您可以使用各种有趣的选项:

  • 做一个普通的香草合并。把一切都带进疣。

  • 做一个变基。允许您对分支历史进行排序,重新排列提交顺序,将提交扔出,将提交连接在一起,重新编写提交消息-甚至是编辑提交或添加新的! 一个分布式版本控制系统对代码检查有很深的支持。

一旦我了解了本地存储库如何允许我出于对程序员的同情和未来自我的考虑而编辑历史,就永远挂断SVN。我的Subversion客户现在是git svn

允许开发人员和管理人员对提交历史记录行使编辑控制权可以带来更好的项目历史记录,并且可以使用干净的历史记录确实提高了我作为程序员的工作效率。如果所有有关“重写历史记录”的讨论都吓到了您,请不要担心,因为这是中央,公共或主存储库的用途。历史可能(并且应该!)被重新编写,直到有人将其带入其他人正在从中获取的存储库的分支中。那时,历史应该被视为刻在石碑上。

46
Sharpie

dukofgamings的答案大概是可以得到的,但是我想从另一个方向解决这个问题。

让我们假设您说的是绝对正确的,并且通过应用良好实践可以避免DVCS旨在解决的问题。这是否意味着DVCS不会给您带来优势?人们遵循最佳实践。人们正在搞砸了。那么,为什么您要避免设计用于解决一系列问题的软件,而是选择依靠人们去做一些您可以事先预测出他们不会做的事情呢?

18
philosodad

是的,当您必须在Subversion中合并大型提交时,这样做会很痛苦。但这也是一次很棒的学习经历,使您尽一切可能避免合并冲突。换句话说,您将学习 经常签入 。对于任何共处一地的项目,早期集成是一件非常好的事情。只要每个人都在这样做,使用Subversion就不会有太大问题。

例如,Git是用于分布式工作的 设计 ,它鼓励人们从事自己的项目,并为以后的(最终)合并创建自己的叉子。这不是not专为持续集成在“小而高度协作的团队”中而设计的,这是OP所要求的。相反,想一想。如果您要做的只是坐在同一个房间里一起使用相同的代码,那么您将无法使用其精美的分布式功能。

因此,对于一个位于同一地点且使用CI的团队,我真的认为,不管是否使用分布式系统,它都没有太大关系。它归结为口味和经验的问题。

9
Martin Wickman

因为您应该不断挑战自己的知识。您喜欢Subversion,我可以理解,因为我使用了多年,并且对此感到非常满意,但这并不意味着它仍然是最适合您的工具。

我相信,当我开始使用它时,它是当时的最佳选择。但是随着时间的推移会出现其他工具,即使对于我自己的业余时间项目,我现在也喜欢git。

而且Subversion确实有一些缺点。例如。如果您在光盘上重命名目录,则不会在存储库中重命名该目录。不支持文件移动,这使文件移动时执行复制/删除操作,使得在移动/重命名文件时难以合并更改。合并跟踪并不是真正内置于系统中,而是以变通办法的形式实现。

Git确实解决了这些问题(包括自动检测文件是否已移动,您甚至不需要告诉它是事实)。

另一方面,git不允许您像Subversion一样在单个目录级别上分支。

所以我的答案是,您应该研究替代方案,看看它是否比您所熟悉的更适合您的需求,然后再决定。

8
Pete

在性能方面,当您必须从一个分支切换到另一个分支,或从一个修订版本跳到另一个修订版本时,Git或任何其他DVCS都比SVN具有更大的优势。由于所有内容都存储在本地,因此与SVN相比,它们快得多

仅此一项就可以让我切换!

7
Xavier Nodet

而是坚持“通过应用最佳实践,您不需要DVCS”的想法,为什么不考虑SVN工作流程是一个工作流程,却具有一组最佳实践,而GIT/Hg工作流程则是另一个工作流程,具有一系列不同的最佳做法。

git bisect(及其对您的主要存储库的所有影响)

在Git中,一个非常重要的原则是您可以使用git bisect。为此,请使用已知运行的最后一个版本,以及已知运行失败的第一个版本,然后(在Git的帮助下)执行二进制搜索以找出导致该错误的提交。为此,您的整个修订历史记录必须相对没​​有其他会干扰您的错误搜索的错误(信不信由你,这实际上在实践中效果很好,Linux内核开发人员一直在这样做)。

实现 git bisect功能,您可以自行开发一个新功能功能分支,对其进行基础调整并清除历史记录(因此您没有任何已知的非-您历史记录中的有效修订版-只是一堆更改,每个修订版都可以帮助您解决问题),然后在完成功能后,将其合并到具有有效历史记录的主分支中。

另外,要使其工作,您必须对从哪个版本的主分支开始功能分支有所约束。您不能仅仅从master分支的当前状态开始,因为那可能有不相关的错误-因此内核社区的建议是从内核的最新稳定版本开始工作(对于大型功能) ),或从最新的带标签的发行候选版本开始工作。

您还可以同时将功能分支推送到服务器来备份中间进度,也可以将功能分支推送到服务器与他人共享,并在功能完成之前,在必须完成之前征求反馈。将代码转变为项目库中每个人*必须处理的代码库的永久功能。

gitworkflows 手册页很好地介绍了Git设计的工作流程。另外 为什么Git比X更好 讨论git工作流程。

大型分布式项目

为什么我们需要一个具有良好实践和良好设计习惯的高度协作的团队中尉?

因为在Linux之类的项目中,涉及的人员如此之多,而且地理位置如此分散,以至于很难像共享会议室的小型团队那样高度协作。 (我怀疑,对于开发像Microsoft Windows这样的大型产品,即使人们都位于同一栋大楼中,团队规模也太大了,无法保持协作水平,而这种协作水平使集中化的VCS无需使用副手即可工作。)

3
Ken Bloom

为什么不串联使用它们?在我当前的项目中,我们被迫使用CVS。但是,我们还保留本地git存储库以进行功能开发。这是两全其美的imo,因为您可以尝试各种解决方案并在自己的计算机上保留正在处理的版本。这使您可以回滚到功能的早期版本,或尝试几种方法而不会在弄乱代码时引起问题。这样,拥有一个中央存储库将为您带来拥有一个集中存储库的好处。

2
Vadim

我没有DVCS的个人经验,但是根据我在此处的答案和一些链接的文档中得出的结论,DVCS和CVCS之间最根本的区别是使用的工作模型

DVCS

DVCS的工作模型是您正在做隔离开发。您正在与其他所有更改隔离地开发新功能/错误修正,直到决定将其发布给团队的其他成员为止。在此之前,您可以进行任何所需的签入操作,因为没有其他人会为此而烦恼。

CVCS

CVCS(特别是Subversion)的工作模型是您正在做协作开发。您正在与所有其他团队成员直接协作来开发新功能/错误修正,所有更改都将立即提供给所有人。

其他差异

svngit/_hg之间的其他差异是偶然的,例如修订版与变更集。很有可能基于修订创建DVCS(如Subversion拥有修订版)或基于变更集创建CVCS(如Git/Mercurial拥有修订集)。

我不会推荐任何特定的工具,因为它主要取决于您(和您的团队)最适应的工作模型。
就我个人而言,使用CVCS没问题。

  • 我不担心检入内容,因为我可以毫无问题地将其放入不完整但可编译的状态。
  • 当我经历合并地狱时,它是在svngit/_hg中都发生的情况。例如,当我们开发V3时,某些软件的V2由不同的团队使用不同的VCS维护。有时,必须将错误修正从V2 VCS​​导入到V3 VCS,这基本上意味着要在V3 VCS上进行非常大的签入(所有错误修正都在一个变更集中)。我知道这并不理想,但这是使用不同VCS系统的管理决定。
1
Bart van Ingen Schenau