转自:http://www.ydmsh.com/www/Blog/Show/id/147/
不知道什么是版本库的,扇自己两个大嘴巴;知道但不用的,扇自己四个大嘴巴。快扇去。你真扇了?那你是个大傻瓜。扇什么扇,有扇自己的功夫,还不赶紧去用版本库。
上面那句话是我根据《版本控制之道:使用Git》上一句读者感言发展而来的。版本控制真的那么重要,真的那么好吗?
什么是版本控制?[此段写给需要扇自己两个大嘴巴的人,以及部分需要扇四个大嘴巴的人]
版本控制这个东西和许多控制规范等东西一样,用明显的、分散的、定量的、微小的、确定的效率降低,来换取偶然的、集中的、不确定的、严重的效率降低。OK,我承认这句话太唬人了。以后我争取使用汉语普通话来说。其实我也不敢确定刚才那句话是否准确,但至少这是我的理解,很原创的。后面我会很负责人的解释这句话的。
版本库就是一个仓库,你把东西放进去(通常是你编写的程序代码),然后再在需要的时候拿出来。通常这种仓库都有一个很神奇的地方,你不但能看到你放进去的东西现在的样子,还能看到它以前的样子,这就是版本了,同一件东西每次放进去时的样子都会被保留下来,所以你可以追溯这个东西在任何时期的样子。那么控制呢?那就有管理的概念在里面了。首先仓库有自己的结构(通常就是个数据库),进入仓库的东西都按照这一结构存放着,无论你把东西放进还是拿出也要遵循你所用仓库的标准(用专用的版本控制命令或程序),而依靠所提供的程序或命令,你就可以操作这个仓库,控制里面的内容,并且想看某个东西的任何某个版本都可以。
好的,我知道上面那一整段仍然很难理解,我们需要重来一遍。我们先说说什么东西能放到版本库里并进行版本控制呢?通常版本控制是编程人员使用的,管理的是程序的代码。所以版本库首先就是个代码库。其次,每当代码有了修改,编程人员就会把修改后的代码再此提交到版本库中。一次一次的,版本库记录就下了整个项目的代码是如何一步步演化的。如果编程人员想看某段代码以前的样子,那么通过版本库,编程人员可以从版本库里找到曾经这段代码的每一个演化步骤。
更加简明一些,首先是一个存放代码的仓库,其次是一套管理这个仓库的工具,整个构成了一套版本控制系统。
这一段大概就比较明确了。除了最常用的存放程序代码,版本库还可以存放许多其他的东西,比如这篇文章。这篇文章就是在Git版本控制系统的管理下。
有人会说,使用版本控制会影响效率,所以才不要用版本库呢。[这是需要扇自己四个大嘴巴的人]OK,我先把内容“提交”(commit)一下,然后再说这个问题。
版本控制表面上的确会影响效率。虽然当今的版本控制系统使用起来都比较简单,但是仍然不可避免会花去一些学习的时间。为每个人安装版本控制软件也需要时间。可能还要部署和维护一台版本库服务器,不但耗费时间还要花钱。写点什么东西就需要提交,仍然需要花时间。然而这一且的花费怎么看也感觉没有必要,并且也转换不成最终的生产力。
那为什么还要力挺版本控制呢?
世界上无数大大小小的开发项目都在使用各种各样的版本控制系统,原因在于它的优点对于一个项目开发来说是无比重要。
一个最简单的开发团队,也许就两三个人,他们共同完成一个软件的开发。每个人都在修改、添加、删除着自己本地硬盘上的代码,当他们把这些代码汇总起来时,麻烦出现了。到底谁改了哪些文件,具体是文件里的哪部分被改动过?A的修改会不会把B的修改覆盖掉?汇总的工作变得很危险,需要非常小心,一旦出错后果不堪设想。显然此时,效率将会是无比的低下,如果某个地方出错,可能整个汇总工作就要重来一遍。这只是两三人的小团队,如果是几十人几百人的大团队呢?那将会是噩梦。
如果这个团队采用了版本控制。那么版本控制软件在每次提交的时候都会主动合并所有人的修改并解决可能发生的冲突。每个人手里一直都是汇总好的代码。当开发进行到一定阶段,可以直接拿去测试,不需要再有额外的工作来浪费时间。另外,你还可以知道,程序的某个Bug,是怎么出现的(被谁以及什么时候引入进来的)。
上面的那些情况,我有幸亲身经历过。很早以前我就听说过版本控制这个东西,但当时我也认为使用版本控制纯属浪费时间没事找事。但是后来我和我的同事两人共同完成网站项目的时候,出现过多次把对方修改覆盖掉的事情。最终,使我不得不考虑版本控制这个东西。我现在还清晰的记着年三十晚上抱着笔记本写建立Subversion(SVN)版本库方案的情景(其实不过是几年前而已),方案的主要内容好像就是讲述建立版本控制的必要性以及为什么选择SVN。最终这份方案也没有用到,春节过后我只是给我们的LQ领导说了一句(这一句其实还没说完),他就说只要有需要弄就可以。OK,很快SVN服务就在一台现有的Windows Server 2003服务器(所以说没几年时间)上搭建起来并开始使用了。那份方案后来我就没再见过,不知道放哪里去了。
当时,CVS和SVN是我的两个候选,最首先的原因就是开源(如果是商业性的,那么最终只可能去用盗版,这是我不希望看到的)。CVS是非常经典的,当时许多人都在使用,CVS的教程和文档我也看了很多。但最终我选择了SVN,大概是因为许多项目都从CVS转向SVN,其次是有个Subversion中文站翻译的很好的中文教程,还有就是在Windows下有一个很好用的TortoiseSVN。反过来,放弃CVS的直接原因就是CVS比SVN难用了。
这个SVN一直用到现在(同样其实也没几年),效果是非常好的。两个人都可以自由的编辑修改文件内容,却不用考虑另一个人在干什么,大不了发生冲突的时候自己简单改改就可以了,而且出现冲突的次数屈指可数。所以,我的想法发生了彻底得改变。前面说了,以前我认为用版本控制是浪费时间没事找事,现在我认为多人开发团队不用版本控制属于给整个团队找麻烦,团队管理者需要扇自己四个大嘴巴。所以当知道我的同事所在的新单位没有使用版本控制的时候,我是非常惊讶。是的,我的那位同事去年跳槽走了。
当然,在使用SVN时还是出了一些小不足。我们所搭建的结构是所有项目都放在同一个版本库下(不同路径),因为全都是网站项目,所以这是一种很省事并且好维护的方式,但后来发现也挺影响性能的,只是还在容忍范围内。不过还是存在一些有趣的事情,Windows XP与Windows Server间明显比Linux(用RapidSVN)与Windows Server间慢。原因不明,不过我没有深究。考虑SVN在Windows下也是原生程序,不应该差别如此明显,也许是Windows自身对目录等操作的效率引起的吧。
一个团队,选择什么样的版本控制系统,是需要深思熟虑的。如果版本控制建立起来了,再改换其他那会是相当麻烦。如果整个团队都在使用某个IDE(集成开发环境),那么用IDE内置的版本控制(许多IDE都会带)是比较好的选择,原因就是和IDE自身衔接紧密。有些IDE(例如Eclipse)可以通过插件使用多种版本控制系统,以及像我们这样用的工具比较杂通常就用个记事本(有些夸张,我们基本是用notepad++,我在Linux下用Geany)的人,怎么选择用什么样的版本控制系统呢?我认为可以考虑如下几个方面:
1.大家都用什么操作系统,要选择在这个操作系统下速度快的版本控制系统;
2.上手要容易,团队的许多成员可能并不想费力去学习一个表面上看纯属浪费时间的东西,所以能让他们用最少的时间掌握非常重要,哪怕你可以用高压手段逼迫他们学习,但到用的时候简单易用仍然能减少许多不必要的麻烦,毕竟版本库仍然有可能被不懂操作的人弄得一塌糊涂;
3.最适合自己项目以及团队组织形式的版本控制系统。
目前大家最常用的版本控制系统有哪些呢?下面我也简单说说,当然版本控制非常多,我也只知道下面几个,而且都是开源的。
前面提到过的一个叫CVS的,这个很有名,目前可能依然有人用,不过建议大家就不要再考虑了。原因就是太老了,没有人再维护这个东西了,只做纪念了。
前面提到的Subversion,非常流行的一套系统,也是我们(很不幸目前只有我一人了)在用的。Google Code等项目托管站点也在使用。wikipedia中文上列出了一些使用SVN的项目,不过许多项目好像已经迁移到了git上。无论如何,SVN是集中式版本控制的典范,非常优秀。
下面是两个十分有名的分布式版本控制系统。刚才说到SVN是集中式,现在只简单提一句。集中与分布有一个明显的区别,集中式的版本库数据只存在于服务器上(服务器是必须存在的),而分布式的版本库信息存在于每一个开发者的机器上(不一定必须有个服务器)。
Mercurial是目前非常流行的分布式版本控制系统,命令是hg(汞)。Google Code也支持Mercurial,建立项目的时候可以在Mercurial和Subversion之间选择一个。使用Mercurial的其他项目也不少,当你看到要用hg clone命令下载某个项目源码的时候,你就知道这个项目使用Mercurial来管理了。我很坦白,这个东西我没用过,只用hg clone下载过源代码。
由Linux内核的创造者Linus Torvalds所创造的git,是一个概念非常先进的完全分布式版本控制系统。当你用git clone下载项目源代码的时候,你就知道它的存在了。最初开发git的目的是为了管理Linux内核的开发,但现在有许多著名项目已经转到了git(见git官网首页)。git有着非常多的优点,比如刚才说到的完全分布式,这使得git完全不需要服务器(Mercurial好似没能做到这点)。非常高效的分支,建立、合并分支几乎可以瞬间完成,所以git推荐用户大量使用分支。另外依靠上面两个优点,使得它可以实现非常灵活的组织形式,从几人小团队到像Linux开发那样的庞大团队都能找到最适合自己的组织形式。git提供非常好的SVN兼容工具,可以把SVN版本库迁移到git版本库(这也许就是许多过去用SVN的项目转向git的原因吧),或者是在git和SVN混合状态下使用(很有意思的结构,本地git整体SVN,可以解决许多问题)。不过git也有一些比较明显的缺点。有人说命令比较多,上手比较困难(实际上常用命令也就那么几个)。没有好的图形界面程序,基本只能大量用命令。目前没有原生的Windows程序,只有通过minGW的实现,速度就比较慢了。
大家也许会发现,介绍git的那一段我写了许多。那是因为我现在正在使用git。SVN让我了解到团队合作使用版本控制是必须的,而git让我充分了解到哪怕自己一个人做项目版本控制仍然是必要的(虽然在用git之前我已经用svn管理自己个人的项目,也就是目前大家所在的这个网站,但那时候我不会给别人推荐这种做法)。哪一点是必要的呢?保证代码的安全。版本库依旧是记录你个人的每次提交,所以你可以追溯代码的改变,找回以前认为没有用但现在又突然有用的代码。如果用集中式版本控制,你需要建一个版本库和一个工作目录,这对个人来说显然就非常繁琐了。而git这种完全分布式,版本库和工作目录都在一起,一条命令建立完成,使用速度非常快。另外git可以使组织结构非常灵活,虽然它不需要有服务器,但是它仍然可以有服务器。我用一台淘汰下来的笔记本电脑配置了一台简易服务器(我别的文章上提过),上面就有用gitosis-admin管理着的git版本库。我的台式机和其他笔记本最终都把数据“推”(push)到那里统一存放。大家所看到的这个网站,我也使用git自带的迁移工具从SVN转到了git。
扯了许多乱七八糟了,怎么看都有跑题的感觉。最后总结一下。版本控制好处多多,不知道版本控制的人需要多多了解一下,知道版本控制却不去使用的人应该努力改变自己的想法。版本控制带来的好处真的是太多了。