您好,欢迎访问三七文档
第1章版本控制的前世和今生Git权威指南1第1篇:初识GitGit是一款分布式版本控制系统,有别于像CVS和SVN那样的集中式版本控制系统,Git可以让研发团队更加高效地协同工作,从而提高生产率。使用Git,开发人员的工作不会因为频繁地遭遇提交冲突而中断,管理人员也无须为数据的备份而担心。有着像Linux这样的庞大项目的考验,Git可以胜任任何规模的团队,即便这个团队分布于世界各地。Git是开源社区送给每一个人的宝贝,用好它可以实现个人的知识积累、保护好自己的数据,以及和他人分享自己的成果。这在其他的很多版本控制系统中是不可想象的。试问你会仅仅为个人的版本控制而花费高昂的费用去购买商业版本控制工具么?你会去使用必须搭建额外的服务器才能使用的版本控制系统么?你会把“鸡蛋”放在具有单点故障、服务器软硬件有可能崩溃的唯一的“篮子”里么?如果你不会,那么选择Git,一定是昀明智的选择。本篇我们首先用一章的内容回顾一下版本控制的历史,并以此向版本控制的前辈CVS和SVN致敬。在第2章通过一些典型的版本控制的实例向您展示Git独特的魅力,让您爱上Git。在本篇的昀后一章会介绍Git在Linux、MacOSX及Windows下的安装,这是我们下一步研究Git的基础。还有在这里有必要纠正一下Git的发音。一种错误是按照单个字母来发音,另外一种更为普遍的错误是把整个单词读作“技特”,实际上Git中字母G的发音应该是和下列单词中的G类似:GODGIVESGREATGIFT。因此Git正确的发音应该听起来像是“歌易特”。在我的一再坚持下,编辑同意本书的英文名(如果有的话)为《GotGit》,当面对这样的书名时您还会把Git读错么?第1章版本控制的前世和今生除了茫然未知的宇宙,几乎任何事物都是从无到有,从简陋到完善。随着时间车轮的滚滚向前,历史被抛在身后逐渐远去,如同我们的现代社会,世界大同,到处都是忙碌和喧嚣,再也看不到已经远去的刀耕火种、男耕女织的慢生活岁月。版本控制系统是一个另类。虽然其历史并不短暂,也有几十年,但是他的演进进程却一直在社会的各个角落重复着,而且惊人的相似。有的人从未使用甚至从未听说过版本控制系统,他和他的团队就像停留在黑暗的史前时代,任由数据自生自灭。有的人使用着有几十年历史的CVS或其改良版Subversion,让时间空耗在网络连接的等待中。再有就是以Git为代表的分布式版本控制系统,已经风靡整个开源社区,正等待你的靠近。第1章版本控制的前世和今生Git权威指南21.1黑暗的史前时代人们谈及远古,总爱以黑暗形容。黑暗实际上指的是秩序和工具的匮乏,而不是自然,如以自然环境而论,工业化和城市化对环境的破坏,现今才是昀黑暗的年代。对软件开发来说也是如此,虽然遥远的C语言一统天下的日子,要比今天选Java,选.Net,还是选择脚本语言的多选题要简单得多,但是从工具和秩序上讲,过去的年代是黑暗的。看看我经历的版本控制的“史前时代”吧。在大学里,代码分散地拷贝在各个软盘中,昀终我会被搞糊涂,不知道哪个软盘中的代码是昀优的,因为昀新并非昀优,失败的重构会毁掉原来尚能运作的代码。在我工作的第一年,代码的管理并未改观,还是以简单的目录拷贝进行数据的备份,三四个程序员利用文件服务器的共享目录进行协同,公共类库和头文件在操作过程中相互覆盖,痛苦不堪。很明显,那时我尚不知道版本控制系统为何物。我的版本控制史前时代一直延续到2000年,那时CVS已经诞生了14年,而我在那时对CVS还一无所知。实际上,即便是在CVS出现之前的“史前时代”,也已经有了非常好用的源码比较和打补丁的工具:diff和patch,他们今天生命力依然顽强。大名鼎鼎的LinusTorvalds先生(Linux之父)也对这两个工具偏爱有加,在1991-2002年之间,Linus一直顽固地使用diff和patch管理着Linux的代码,即使不断有人提醒他CVS的存在1。那么来看看diff和patch,熟悉它们,将对理解版本控制系统(差异存储),使用版本控制系统(代码比较和冲突合并)都有莫大的好处。1.命令diff用于比较两个文本文件或目录的差异先来构造两个文件:文件hello文件world应该杜绝文章中的错别子2。但是无论使用*全拼,双拼应该杜绝文章中的错别字。但是无论使用*全拼,双拼1LinusTorvalds于2007-05-03在Google的演讲:=4XpnKHJAok82此处是故意将“字”写成“子”,以便两个文件进行差异比较。第1章版本控制的前世和今生Git权威指南3*还是五笔是人就有可能犯错,软件更是如此。犯了错,就要扣工资!改正的成本可能会很高。*还是五笔是人就有可能犯错,软件更是如此。改正的成本可能会很高。但是“只要眼球足够多,所有Bug都好捉”,这就是开源的哲学之一。对这两个文件执行diff命令,并通过输出重定向,将差异保存在diff.txt文件中。$diff-uhelloworlddiff.txt上面执行diff命令的-u参数很重要,使得差异输出中带有上下文。打开文件diff.txt,会看到其中的差异比较结果。为了说明方便,为每一行增添了行号。1---hello2010-09-2117:45:33.551610940+08002+++world2010-09-2117:44:46.343610465+08003@@-1,4+1,4@@4-应该杜绝文章中的错别子。5+应该杜绝文章中的错别字。67但是无论使用8*全拼,双拼9@@-6,6+6,7@@1011是人就有可能犯错,软件更是如此。1213-犯了错,就要扣工资!14-15改正的成本可能会很高。16+17+但是“只要眼球足够多,所有Bug都好捉”,18+这就是开源的哲学之一。上面的差异文件,可以这么理解:第1、2行,分别记录了比较的原始文件和目标文件的文件名及时间戳。以三个减号(---)开始的行标识的是原始文件,以三个加号(+++)开始的行标识的是目标文件。在比较内容中,以减号(-)开始的行是只出现在原始文件中的行,例如:第4、13、14行。第1章版本控制的前世和今生Git权威指南4在比较内容中,以加号(+)开始的行是只出现在目标文件中的行,例如:第5、16-18行。在比较内容中,以空格开始的行,是在原始文件和目标文件中都出现的行,例如:第6-8、10-12、15行。这些行是用作差异比较的上下文。第3-8行是第一个差异小节。每个差异小节以一行差异定位语句开始。第3行就是一条差异定位语句,其前后分别用两个@进行标识。第3行定位语句中-1,4的含义是:本差异小节的内容相当于原始文件的从第1行开始的4行。而第4、6、7、8行是原始文件中的内容,加起来刚好是4行。第3行定位语句中+1,4的含义是:本差异小节的内容相当于目标文件的从第1行开始的4行。而第5、6、7、8行是目标文件中的内容,加起来刚好是4行。命令diff是基于行比较,所以即使改正了一个字,也显示为一整行的修改(参见差异文件第4、5行)。Git对diff进行了扩展,还提供一种逐词比较的差异比较方法,参见本书第2篇“11.4.4差异比较:gitdiff”小节。第9-18行是第二个差异小节。第9行是一条差异定位语句。第9行定位语句中-6,6的含义是:本差异小节的内容相当于原始文件的从第6行开始的6行。而第10-15行是原始文件中的内容,加起来刚好是6行。第9行定位语句中+6,7的含义是:本差异小节的内容相当于目标文件的从第6行开始的7行。而第10-12、15-18行是目标文件中的内容,加起来刚好是7行。2.命令patch相当于diff的反向操作有了hello和diff.txt文件,可以放心地将world文件删除或用hello文件将world文件覆盖。用下面的命令可以还原world文件:$cphelloworld$patchworlddiff.txt也可以保留world和diff.txt文件,删除hello文件或用word文件将hello文件覆盖。用下面的命令可以恢复hello文件:$cpworldhello$patch-Rhellodiff.txt命令diff和patch还可以对目录进行比较操作,这也就是Linus在1991-2002年用于维护Linux不同版本间差异的办法。可以用此命令,在没有版本控制系统的情况下,记录并保存改动前后的差异,还可以将差异文件注入版本控制系统(如果有的话)。第1章版本控制的前世和今生Git权威指南5标准的diff和patch命令存在一个局限,就是不能对二进制文件进行处理。对二进制文件的修改或添加会在差异文件中缺失,进而丢失对二进制文件的改动或添加。Git对差异文件格式提供了扩展支持,支持二进制文件的比较,解决了这个问题。这点可以参考本书第7篇“第38章补丁中的二进制文件”的相关内容。1.2CVS——开启版本控制大爆发CVS(ConcurrentVersionsSystem)1诞生于1985年,是由荷兰阿姆斯特丹VU大学的DickGrune教授实现的。当时DickGrune和两个学生共同开发一个项目,但是三个人的工作时间无法协调到一起,迫切需要一个记录和协同代码开发的工具软件。于是DickGrune通过脚本语言对RCS(一个针对单独文件的多版本管理工具)进行封装,设计出有史以来第一个被大规模使用的版本控制工具。在Dick教授的网站上介绍了CVS这段早期的历史。2“在1985年一个糟糕的秋日里,我站在校汽车站等车回家,脑海里一直纠结着一件事——如何处理RCS文件、用户文件(工作区)和Entries文件的复杂关系,有的文件可能会缺失、冲突、删除,等等。我的头有些晕了,于是决定画一个大表,将复杂的关联画在其中看看出来的结果是什么样的……”1986年Dick通过新闻组发布了CVS,1989年由BrianBerliner将CVS用C语言重写。从CVS的历史可以看出CVS不是设计出来的,而是被实际需要逼出来的,因此根据实用为上的原则,借用了已有的针对单一文件的多版本管理工具RCS。CVS采用客户端/服务器架构设计,版本库位于服务器端,实际上就是一个RCS文件容器。每一个RCS文件以“,v”作为文件名后缀,用于保存对应文件的历次更改历史。RCS文件中只保留一个版本库的完全拷贝,其他历次更改仅将差异存储其中,使得存储变得非常有效率。我在2008年设计的一个SVN管理后台pySvnManager3,实际上也采用了RCS作为SVN授权文件的变更记录的“数据库”。图1-1展示了CVS版本控制系统的工作原理,可以看到作为RCS文件容器的CVS版本库和工作区目录结构的一一对应关系。1://~dick/CVS.html3第1章版本控制的前世和今生Git权威指南6图1-1:CVS版本控制系统示意图CVS的这种实现方式的昀大好处就是简单。把版本库中随便一个目录拿出来就可以成为另外一个版本库。如果将版本库中的一个RCS文件重命名,工作区检出的文件名也相应地会改变。这种低成本的服务器管理模式成为很多CVS粉丝至今不愿离开CVS的原因。CVS的出现让软件工程师认识到了原来还可以这样工作。CVS成功地为后来的版本控制系统确立了标准,像提交(commit)、检入(checkin)、检出(checkout)、里程碑(tag)、分支(branch)等概念早在CVS中就已经确立。CVS的命令行格式也被后来的版本控制系统竞相模仿。在2001年,我正为使用CVS激动不已的时候,公司领导要求采用和美国研发部门同样的版本控制解决方案。于是,我的项目组率先进行了从CVS到该商业版本控制工具的迁移1。虽然商业版本控制工具有更漂亮的界面及更好的产品整合性,但是就版本控制本身而言,商业版本控制工具存在着如下缺陷。采用黑盒子式的版本库设计。
本文标题:git权威指南
链接地址:https://www.777doc.com/doc-4285927 .html