现象,近年来,我们对版本控制工具的关注点似乎正在改变.起初,我们主要也是唯一的目的就是对代码进行监控,使我们能够安全的返回到旧的版本,以便我们能够诊断代码中的问题.后来,我们的关注点更侧重于如何使人与人之间的合作更为顺畅. 这个关注点并不是要取代对代码的监控,而是以代码监控为基础,并建立于其上的.现在,我们又越来越关注使用这些工具来描述代码的变更,因此就出现了对于重写代码历史命令(history rewriting command)的需求.当然,对代码变更的描述也同样需要建立在前两种关注点之上.
我们可以把版本控制工具的应用分为六个层次:
0. 没有版本控制
完全没有版本控制的解决方案,或者就使用一个共享的文件系统,并对其做定期的备份.一个开发人员,或者最多几个开发人员在没有工具的情况下共享代码,其面临的风险可想而知:
1. 初步的探索
这时的工具有了基本的版本控制功能,如checkout,版本记录和锁文件.通常这就意味着开发人员在同一份代码上工作,而代码的同步就会依赖于每个人代码文件的锁状态.这种工具在扩展和长期工作上都会有问题.对资源的重命名难到几乎不可能完成.Branching和Tagging操作则会需要同时操作三份代码的权限,而且可能还需要一个宰好的或者两柱香.如, VSS.
2. 笨拙
如CVS和TFS.
3. 基本成型
如Subversion.
4. 有效并且可靠
如Perforce.
5. 高速,无形,高度可用
如Git和Mercurial.
通过前面版本控制工具的演化过程,我们基本上可以看到分布式工具的特点和优势了.相对于以往的客户-服务器端的集中式系统,它所采用的是一种P2P的方式.客户端不再需要从一个单一的中央代码库同步代码,每一个端点的代码的拷贝都是真正的代码库.分布式的版本控制系统是通过端点之间交换补丁(patch)的方式来同步代码的,而这种方式就决定了分布式系统与集中式系统的几个重要的区别:
现在的项目用的是Subversion做版本控制,但是我们自己用的是git-svn,这里主要通过这两种有代表性的工具来比较一下集中式和分布式工具的优势.
Subversion提倡单一的中央代码库模型,不提倡大规模的branching.在一个使用持续集成的环境中,其实也就是我们每天工作的环境,这个模型是非常合适的.这也是Subversion为什么这么流行,应用范围这么广的原因之一.
虽然分布式的系统使你拥有足够的灵活性来自己安排自己的工作流程,但是其实大多数人的工作模式仍然是使用持续集成,这也就意味着需要一条可以共享的代码库主线.现在的版本控制系统已经有了神奇的合并工具,但这些合并仍然只限于文本.所以对于语义上的一致,仍然需要持续集成来保证.结果就是即使一个团队在使用分布式的版本控制系统,他们仍然会需要一个主版本库.
即使如此,分布式系统仍拥有一些SVN无法提供的体验.
在某种特定情况下,SVN也有其相应的优势,如果你需要对版本控制系统难以合并的二进制文件(如word文档或者ppt)进行管理的话,你就应该回退到独占式checkout的锁机制下,这就需要一个集中式的系统.另外,SVN更容易上手:你有一个代码库,所有的更改都指向这个代码库,如果你知道如何创建,提交以及checkout,那你就可以开始使用它了,而像branching,更新这些操作在使用过程中自然也就慢慢熟悉了.SVN拥有一些非常好用的客户端软件,而且几乎所有的主流IDE都有与SVN集成的插件,这些都能够为你使用SVN提供很大的帮助.
Git则增加了复杂性,似乎总是有两种模式来进行操作,checkout和clone, commit和push...... 你得知道哪些命令是针对本地进行操作的,哪些命令是对服务器或者是主代码库进行操作的. 实际上,Git的命令和思维模式与其它的版本控制系统是有所不同的.Bulter Cole曾这样形容Git:"它是一个神奇的功能强大的东西,它几乎可以做任何你让它做的事情,只有你知道如何让它做".Git的反对者也会抱怨Git缺少可发现性,你很难从它的表面设计推断出它的行为.而Git的支持者则认为这只是因为Git使用了不同于其它系统的思维模式,你需要先忘掉以前那些关于版本控制系统的知识才能更好的来欣赏Git.无论如何,Git对于那些喜欢研究事物内部工作机制的人来说,还是非常有吸引力的.
通常来讲,Git相比Mercurial在处理branching方面表现更好,尤其是用于试验和检查点的短期branch.Mercurial提倡是另一种机制,例如快速的clone一份代码库或者是使用补丁,但是Git的branching模式更为简单好用.Mercurial在处理大型二进制文件时同样有问题.通常的建议是使用SVN来管理二进制文件,如果你只有很少的二进制文件需要管理,不值得建立单独的管理机制的话,Mercurial将就着也能处理.
此外Git之所以能在网络上引起如此多的共鸣,有一个很大的原因是Git对于开源项目来说是完善的选择.你可以新建一个项目分支,向你自己的项目分支提交修改,然后让项目维护人员将你的修改pull过去.有了Git,这一切就变得如此的方便和自然.即使你没有向项目提交修改的权限,你也可以在线上建立你自己的代码库,将你自己的补丁发布出来,任何喜欢你补丁的人都可以将它们pull到他们自己的代码库中,当然也包括项目维护人员.
Git有一个被称为"staging area"的区域.在你向代码库提交之间, 你可以在这个中间区域中构建你的提交.更为重要的是,你可以只提交部分的修改,而不是将所有修改的文件都进行提交.你甚至可以只提交一个文件中修改的一部分.
Git非常的灵活,非常的TIMTOWTDI(There is more than one way to do it). 你可以使用任何你喜欢的工作流程,Git都会对其提供支持.
当前主要的工作流程有以下几种:
1. SVN形式
集中式的工作流程,这也是一种非常普遍的Git的工作流程.如果在你上一次fetch代码之后有其他人进行了提交,那么Git将不允许你向主代码库中push你的代码.
2. 集成管理形式
在这个工作流程中有一个集成管理人员,他向"blessed"代码库进行提交,其他开发人员从这个代码库clone代码,在他们自己的代码库中push修改,并让集成管理人员pull他们的修改.这其实就是大多数开源项目和GitHub所经常使用的开发模式.
3. 独裁者和中尉形式
对于更大规模的项目来说,你可以将开发人员的开发模式设置成类似于Linux内核的开发模式.某些人会负责项目的某个特定的子系统(中尉),并且将所有关于这个子系统的修改都进行合并.另外会有一个集成者(独裁者)可能从他/她的中尉那里pull代码的修改,并将"blessed"代码库进行提交.而所有人都可以从"blessed"代码库进行代码的拷贝.
再次强调,Git对于工作流程的支持非常的灵活,你可以根据自己的需要来匹配,混合,选择这些工作流程.
我们再来看看相对于SVN,Git还有哪些优点吧:
据说目前Git不支持代码库的部分checkout/clone,但是正在开发中,而且已经有submodule方面的支持.SVN则可以根据需要只从代码库中checkout某个子文件夹.SVN的版本号更短并且可以预知,而Git的版本号则是40位的16进制数字串.而Git在Branch方面的处理应该是有很大的优势,但是由于我目前为止几乎没有使用过branch,所以这一部分还没有深刻的体会.
转自:http://www.uml.org.cn/pzgl/201207264.asp