git是每个程序员必备的工具之一,但对于他们来说,git的学习过程并不轻松,主要原因是因为它比较晦涩难懂,即便你去查找git的定义,也不一定能理解这货有什么用?为什么所有程序员都会使用它?下面是git在wikipedia中的解释:
git(GNU Interactive Tools)是一个分布式版本控制软件。
小白第一次读到这个解释时,心里肯定在想:能说点人话吗?什么是GNU?什么是版本控制软件?于是为了照顾初学者的情绪,很多人对git的解释给出了很好的类比,例如:
git就像小叮当的时光机,它能帮你把代码恢复到过去的任意一个时刻。
这个解释很形象,因为所有人都知道小叮当的时光机是什么,这样一下子就和初学者拉近了距离,在众多类比中,我认为最好的一个是:
git是你在玩游戏时的存档,当你game over时,你不需要重新开始,就可以接着上一次存档的地方继续。
存档是游戏通关中的重要手段,它能极大的提升游戏的乐趣性,因为没有人愿意一遍又一遍的从零开始,写代码也一样,如果你对当前的代码不满意,又不想手动恢复一个个源文件,更不想重来一遍,那么最好的办法是,通过git回退到上一次满意的地方。这个功能对新手也是极为重要的,因为新手引进bug的可能性极大,同时他们没有很好的解决bug的能力,这时对他们来说最有效的方法可能就是恢复到上一个正常的状态,然后一点点的敲入新代码,看自己是从哪个地方把bug引进来的。所以,从这个角度来说,
git是程序员在高空作业下的防护网。
读完以上文字,你应该是对git有了一定的了解,但如果你回过头再来查看一下git的定义,你会发现git应该还有其他功能,没错,从interactive这个词来说,git是具备多人协作的功能的,这其实也是git的众多功能中最重要的。
在过去,公司里共享文件时,经常会搭建一个smb服务器,然后把文件放在这个服务器上,所有的同事都可以访问这些文件,并且可以基于这些文件进行修改,如果共享的是word文件,还可以通过word的修订功能,查看谁,在什么时间,修改了哪些内容,但这仅限于word文件,对于程序这种极其复杂的工程管理,smb显然是无能为力。
为此,程序员便开发出了CVS和SVN两种版本控制系统,它提供了很多便利于工程管理的特性,例如保存了文件的差异性,可以为不同的版本创建不同的分支,可以为提交打上标签,下面简单说下这几个概念
- 保存了文件的差异性 - 只要纳入到版本管理系统中的文件,任何变更都会被记录下来,方便维护,例如可以通过该功能查看某个开发者修改了哪些内容——这被称作code review,他是否引入了新bug
-
分支(branch) - 还是为了工程管理,在开发过程中,我们一般会为软件创建两个不同的版本:开发版和稳定版,这两个版本在版本管理系统中对应着两个不同的分支,更一般的,稳定版是由开发版合并而来的。下图可以很好的说明这两个分支间的关系
-
标签(tag) - 通过分支管理还不够,标签的作用是为了让已发布的软件更为直观,同时帮助团队使用统一的语言进行沟通。例如,项目经理需要确认某次bugfix要合并到哪个版本,或除了开发以外,测试同学也需要知道运行在生产环境中的版本号,以便在对应的版本上提交bug。这往往需要借助标签的功能,标签其实是将某一次提交和一个具体的版本号关联在一起的功能,虽然很简单,但它极大的促进了团队间的沟通,因为涉及到项目的所有人都可以基于版本号进行交流了。下图在branch的基础上,增加了tag功能
既然CVS和SVN已经可以进行满足工程管理的需要,那为什么还会有git呢?git是由Linux之父Linus Torvalds开发的,最初被用来管理Linux内核,因为Linux内核的代码量非常庞大,它对版本管理软件的性能要求很高,又因为本着开源精神,这套内核代码需要使用一款开源软件来管理,而现成的CVS和SVN方案,由于架构和性能欠佳不符合要求,所以Linus便亲自花了十天的时间,写出了git的第一个版本。
git的性能极佳体现在它是一个分布式的系统,每一个节点都是一个完整的代码仓库,这和最近火热的比特币有点类似——每个节点都保存了一个完整的账本。在我看来,速度快体现在两个方面:
- 几乎所有操作都是本地操作
- 分支创建非常轻量
先说第1点,由于每个节点都是一个完整的代码仓库,所以可以做到很多操作都在本地进行,也即可以在本地进行“存档”和“回退”操作,甚至都不需要联网,你只用在必要的时候将本地代码上传到远程仓库。操作快速和可以随时“存档”极大的提升了程序员的开发体验。
除了可以随时“存档”外,开发者还可以任性的创建分支,这是我们要说的第2点,因为git创建一个分支非常快,它不会做任何的文件复制操作,只会在已有分支的基础上,新建一个“分支名”,除此之外,git不会像其他版本管理系统一样,将文件和改动分开来管理,而是直接管理文件的快照,对快照的管理会减少CPU的计算量,进一步提升了分支的操作速度。
由于分支的创建、切换和删除都非常迅速和轻量,开发者便可以在任意改动前,先创建一个分支,在新的分支上修改完毕后,再合并到主分支上,目前我所在的团队就是这样的开发模式,同时这也是github的开发模式。下图是这种模式的一个示例:
总结,以上简要的介绍了git是什么,git被用来解决什么问题,它在项目管理中的首要作用,以及它和其他版本管理系统的区别及优势,git是一个非常强大的软件,它不仅可以解决开发过程中的问题,即便对于非开发者,你也可以使用git和其他人共同协作,甚至,你还可以用git来写书。所以,不管是否是程序员,学一下git还是很有必要的。
下一篇我会介绍一下项目协同中,git工作流的使用。