前言Git权威指南i前言版本控制是管理数据变更的艺术,无论数据变更是来自同一个人,还是来自不同的人(一个团队)。版本控制系统不但要忠实记录每一次数据变更,还要能够帮助还原任何历史改动,以及实现团队的协同工作等。Git就是版本控制系统中的佼佼者。我对版本控制系统的兴趣源自于我在个人知识管理中的实践,其核心就是撰写可维护的文档,并保存于版本控制系统中。可维护文档的格式可以是DocBook、FreeMind、reStructuredText等。我甚至还对FreeMind加以改造以便让其文档格式更适合于版本控制系统,这就是我的第一个开源实践:托管于SourceForge上的FreeMind-MMX项目1。文档的书写格式问题解决之后,就是文档的存储问题了。通过版本控制系统,很自然地就可以实现对文档历史版本的保存,但是如何避免因为版本控制系统瘫痪而导致数据的丢失呢?Git用其崭新的分布式的版本控制设计提供了昀好的解决方案。使用Git,我的知识库不再只有唯一的版本库与之对应,而是可以通过克隆操作分发到不同的磁盘上、主机上,克隆的版本库之间通过推送(PUSH)和拉回(PULL)等操作进行同步,数据安全得到了极大的提升。在版本控制系统的忠实呵护下,我的知识库中关于Git的FreeMind脑图日积月累变得越来越详实、越来越清晰,昀终成为这本书的雏形。版本控制还能决定项目的成败甚至公司的生死,此言不虚。我在推广开源的项目管理工具和对企业进行顾问咨询的过程中,看到过太多的团队,因为版本控制系统的管理混乱,导致项目延期、修正的Bug重现、客户的问题不能在代码中定位,无论他们用了什么版本控制系统,开源的或是商业的。而我的公司也同样经历了代码管理的生死考验。因为公司的开发模式主要是基于开源软件的二次开发,在昀早使用SVN(Subversion)做版本控制时,很自然使用了SVN卖主分支模型来管理代码。随着增加和修改的代码越多,和开源软件上游的偏离也越远,当上游有新版本发布时,昀早可能只用几个小时就可以将改动迁移过去,但是如果对上游的改动多达几十甚至上百处时,迁移的过程会异常痛苦,基本上和重新做一遍差不多。那时似乎只有一个选择:不再和上游合并,不再追踪上游的改动,而这和公司的价值观“发动全球智慧为客户创造价值”相背。迷茫之中,分布式版本控制系统飘然而至,原来版本控制还可以这么做。昀先尝试的分布式版本控制系统是Hg(Mercurial),尤其是当发现Hg和MQ(Hg的一个插件)这一对儿宝贝的时候,让我如获至宝。逐渐的,公司的版本库都迁移到Hg上。但随着新1前言Git权威指南ii的开发人员的加入,问题出现了,即一个人使用Hg和MQ都很好,但多个人使用则出现难以协同的问题。于是我们大胆地采用Git,并在实践中结合Topgit等工具进行代码的管理。再一次,也许是昀后一次,我们的代码库迁移到Git。昀早认识分布式版本控制,源自于我们看到了众多开源项目的版本控制系统大迁移,这场迁移还在进行中。MoinMoin是我们关注的一个开源的维基软件,2006年,它的代码库从SVN迁移到Hg1。Mailman同样是我们关注的一个开源邮件列表软件。2007年,它的代码库从SVN迁移到Bazaar2。Linux采用Git做版本控制系统(一点都不奇怪,因为Git就是LinusTorvalds开发的)。Android是昀为流行的开源项目之一,因为潜在的市场巨大,已经吸引越来越多的开发者进入这个市场,而Android就是用Git维护的。当开源软件纷纷倒向分布式版本控制系统的大旗(尤其是Git)的时候,公司也在行动了,尤其是涉及异地团队协同,以及Android核心代码定制开发的公司。对于一些因保守而不敢向Git靠拢的公司,Git也可以派上用场,这是因为Git可以和现在大多数公司部署的SVN很好地协同,即公司的服务器是SVN,开发者的客户端使用Git。相信随着Git的普及,以及公司代码管理观念上的改进,会有更多的公司拥抱Git。本书的组织本书共分8篇41章及附录。第1篇是Git的概览,共分3章。在第1章介绍了版本控制的历史之后,第2章用十来个小例子介绍了一些Git的闪亮特性,期待这些特性能够让您爱上Git。第3章则介绍Git在三种主要的平台上的安装和使用。本书的写作过程中,70%的时间是使用DebianLinux操作系统,对于Linux用户可以毫无障碍的完成本书列举的所有相关操作。在2010年底,当得知有出版社肯以稿酬支持本书的首印后,我向妻子阿巧预支未来的部分稿费购买了我的第一台MacBookPro,于是就有了本书较为详实的MacOSX下Git的安装和使用,以及在本书第4篇第22章介绍的Topgit在MacOSX的部署和改进。在本书的编辑和校对过程中因为要使用Word格式的文稿,所以本1://wiki.list.org/display/DEV/Home前言Git权威指南iii书后期很多工作是在运行于VirtualBox下的Windows虚拟机中完成的,即使是使用运行于资源受限的虚拟机中的Cygwin,Git依然完美的完成了工作。第2篇和第3篇介绍Git的基本操作,是本书的基础和核心,篇幅大约占据全书的百分之四十。这两篇的内容架构实际上是我在进行SVN培训时就已经形成的习惯,即以“独奏”指代一个人的版本控制所要讲述的知识点,以“和声”指代团队版本控制涉及到的话题。在第2篇Git独奏中将Git的设计原理穿插在各章之中,因为唯有了解真相(Git原理),才有可能自由(掌握Git)。在第3篇Git和声中,介绍团队版本控制必须掌握的里程碑和分支等概念,以及如何解决合并中遇到的冲突。第4篇介绍在实际的工作中Git的使用模式。除了传统的集中式和分布式使用模式之外,在第22章介绍了Topgit在定制开发中的应用,这也是我公司昀主要的使用Git的模式。在这一章还介绍了我对Topgit所做的部分改进,对相关改进的介绍昀早出现在我公司的博客上1。第23-25章介绍了多版本库协同的不同方法,其中第25章介绍的一个独辟蹊径的解决方案是由Android项目引入的名为repo的工具实现的,我对其进行的改造可以让这个工具能够脱离Gerrit代码审核服务器,直接操作Git服务器。第26章介绍了git-svn这一工具,不但可以用该工具实现SVN版本库到Git版本库的迁移,还可以实现Git做为客户端向SVN提交。第5篇介绍Git服务器的架设。本篇是全书昀早开始撰写的部分,这是因为我给客户做的Git培训的讲义相关部分不够详细,应客户要求对Gitolite等服务器架设撰写了详细的管理员手册,就是本书的第30章。第32章介绍Android项目在Git管理上的又一大创造,即Gerrit,它实现了一个独特的集中式Git版本库管理模型。第6篇介绍Git版本库的迁移。其中第34章详悉介绍了CVS版本库到Git版本库的迁移,其迁移过程也可以作为CVS到SVN迁移的借鉴。本篇还介绍了SVN和Hg版本库到Git的迁移。对于其他类型的版本库,介绍了一个通用的需编程实现的方法。在本篇的昀后介绍了一个Git版本库整理的利器,可以理解为一个Git库转换为另外一个Git库的方法。第7篇介绍Git的其他应用,其主要部分是介绍我在etckeeper启发下开发的一款备份工具Gistore,该工具可以运行于Linux和MacOSX下。第8篇称为Git杂谈。其中第40章的内容可供跨平台的项目组借鉴。第41章介绍了一些前面没有涉及到的Git相关功能和特性,缺少这些相关内容会有损于杨福川编辑为本书所起的宏大的书名。1前言Git权威指南iv第9篇附录,先是介绍了完整的Git命令索引,然后分别介绍CVS、SVN、Hg与Git之间的比较和命令对照,对于有着其他版本控制系统使用经验的用户,这一部分可供参考。适用读者这本书适合所有翻开它的人,因为我知道这本书在书店里一定是放在计算机图书专柜。为数据同步困扰的电脑人困扰“电脑人”的一个问题是,有太多的数据需要长久保存,有太多的电脑设备需要数据同步。可能有的人会说:“像Dropbox一样的网盘可以帮助我呀”。是的,云存储就是在技术逐渐成熟之后应运而生的产品,但是依然解决不了几个问题:多个设备上同时修改造成的冲突;冗余数据传输造成的带宽瓶颈;还有就是没有实现真正的完全的历史变更数据备份。具体参见本书第7篇第39章的内容。Git可以在数据同步上做的更好,甚至只需借助小小的U盘,就可以实现多台电脑数据同步,并且支持自动的冲突解决。只要阅读本书第1、2篇,就会掌握相关操作,实现数据的版本控制和同步。学习计算机课程的学生我非常后悔没有在学习编程的第一天就开始使用版本控制,很多还在学校时写的一些小程序、函数库都丢失了。在使用CVS、SVN对个人数据进行版本控制之后,才开始把每一天的变更历史都保留下来。Git在这方面可以比CVS、SVN等做得更好。在阅读过本书第1、2、3篇掌握了Git基础之后,可以阅读第5篇第33章的内容,通过Github或类似的服务提供商建立自己的版本库托管,为自己的数据找一个安全的家。程序员开源软件会帮助程序员打开视野,提升水平,增加择业的砝码,而Git会帮助程序员打开进入开源软件之门。看看使用Git做版本控制的开源软件吧:Linuxkernel、Android、Debian、Fedora、GNOME、KDevelop、jQuery、Prototype、PostgreSQL、RubyonRails,...太多太多。还不要忘了所有的SVN版本库都可以用Git方式更好地进行访问。做为一个程序员,团队协同能力必不可少,本书第3篇应该做为学习的重点。前言Git权威指南vAndroid程序员如果您是谷歌Android项目的参与者,尤其是驱动开发和核心开发的参与者,必然要接触Git、repo和Gerrit。对于只是偶尔参考一下Android核心代码的Android应用开发开发人员,也需要对repo深入理解,这样才不致于每次为同步代码花掉一天的时间。repo是Android为了解决Git多版本库管理问题而设计的,在本书第4篇第25章予以介绍。Gerrit是谷歌为了避免因分布式开发造成项目分裂而创造的工具,打造了Android独具一格的集中式管理模式,在本书第5篇第32章予以介绍。即使是非Android项目,也可以使用这两款工具为自己的项目服务。我还为repo写了几个新的子命令可以实现脱离Gerrit提交,让repo拥有更广泛的应用领域。定制开发程序员当一个公司的软件产品需要针对不同用户进行定制开发,就需要在一个版本库中建立大量的特性分支,使用SVN的分支管理远不如用Git的分支管理那么自然和方便。还有一个领域就是对第三方代码进行维护。当使用SVN进行版本控制时,昀自然的选择是卖主分支,而一旦定制开发愈加深入和上游的偏离也越大,和上游代码的合并将痛苦不堪。第4篇第22章会介绍Topgit这一杀手级工具,是这个领域昀佳的解决方案。SVN用户商业软件研发团队因为需要精细代码授权不会轻易更换现有的SVN版本控制系统,这种情况下Git依然大有作为。无论是因为出差在外,或是在家办公,或是因为开发团队分处异地,会遇到SVN版本控制服务器无法访问或速度较慢的情况。这时git-svn这一工具会将Git和SVN完美结合在一起,既严格遵守了SVN的授权规定,又可以自如的本地提交,当能够连接到SVN服务器时,可以悠闲的喝着绿茶,等待一次性批量提交的完成。我有几个项目(pySvnManager,Freemind-MMX)托管在SourceForge的SVN服务器上,现在都是通过git-svn将其转化为本地的Git库然后再使用的。这样访问历史数据、代码比较、提交代码,再也不必因为网速太慢而望眼欲穿了。本书第4篇第26章会向您详细介绍Git和SVN的互操作。管理员在