前言

Git是目前业界最流行的版本控制系统Version Control System,而 GitHub是开源代码托管平台的翘楚。

 

Git和GitHub的区别及联系

注意,虽然二者联系紧密,但是从本质上来说他们是不同的概念。

Git 是一个开源的分布式版本控制系统。而 GitHub 本质上是一个代码托管平台,它提供的是基于 Git 的代码托管服务。对于一个团队来说,即使不使用 GitHub,他们也可以通过自己搭建和管理 Git 服务器来进行代码库的管理,甚至还有一些其它的代码托管商可供选择,如 GitLab,BitBucket 等。值得一提的是 Git 作为一个开源项目,其代码本身就被托管在 GitHub 上。

 

版本控制系统简介

在现代软件项目中,版本控制系统是项目配置管理不可或缺的一部分,甚至是其核心工具。版本控制最主要的任务是追踪文件的变更。无论是应用系统源代码、项目配置文件,还是项目过程的开发文档,甚至是网站界面图片、Logo,都可以且应该被版本控制系统所管理起来,以方便我们在项目的生命各周期能够追踪、查看到软件系统的变更和演进。版本控制系统另一个重要的作用是方便开发者进行协调开发,使得项目中各开发者能够在本地完成开发而最终通过版本控制系统将各开发者的工作合并在一起进行管理。

总结一下,既然名字都叫做版本控制系统VCS,那么其管理控制的内容必然是软件的各个版本,具体的内容必然是软件各个版本的文件,所以管理控制跟踪的主要内容就是这些文件的变更。

集中式版本控制

早期的版本控制系统大多是集中式Centralized版本控制系统。所谓集中式,即是此类系统都有一个单一的集中管理的服务器。在该服务器上保存着项目所有文件以及文件的历史版本,而各开发者可以通过连接到该服务器读取并下载得到文件的最新版本,也可以检索文件的历史版本。开发者常常可以只需要下载他们所需要的文件。通过连接集中式服务器来获取文件和文件更新是集中式版本控制系统的标准做法。业界主流的集中式版本控制系统包括 CVS、SVN、Perforce 等。

集中式版本控制很大程度上解决了版本控制和协同开发的问题,但是它也有重大的缺点。如果中央服务器出现宕机,那么开发者将无法提交代码,也无法进行协同工作,更无法查看文件历史。如果服务器出现更严重的磁盘损坏,又没有进行恰当的备份,那么很大可能将丢失掉项目文件以及项目的变更历史。而各协同开发者在自己本地因为也只有当前版本的文件,或者只有部分文件,很难根据各开发者的本地库对项目的历史记录进行恢复。

总结一下,集中式版本控制,是将所有的版本信息都存放在一个中央的服务器中,所以这种集中式版本控制系统的核心是中央服务器,有一种中央集权的意思在这里。如果当所有的信息全都掌握在一个人手中,那么缺点也很明显,就是当这个人丢失了这些信息,就很难找回了,因为这些信息只有这个人拥有,其他人并不拥有这些信息或者说只拥有其中的一小部分。同时,这也会带来信息不对称。

分布式版本控制系统

相比较集中式的版本控制,目前业界最流行的版本控制系统是分布式   Distributed版本控制系统,其最大的特点是各开发者本地所复制的不仅仅是当前最新版本的文件,而是把代码仓库完整地从服务器上克隆了下来。各开发者本地拥有代码仓库所有的文件以及文件历史和变更信息。这样即使服务器出现宕机,也不影响开发者本地开发,开发者也可以随时查看文件的各历史版本。甚至服务器出现故障导致数据丢失时,项目组也很容易根据开发者的本地代码库恢复出所有文件和文件的历史变更记录。

Git是业界目前最为流行的分布式版本控制系统,除此之外还有 Mercurial、BitKeeper 等。

总结一下,分布式版本控制系统就像是分权,也意味着信息对称,每个人都能共享这些信息,这也意味着信息的公开。同时,集中式所带来的危害在分布式这里就能够得到很好的解决。

拿一个集体的账单来说明集中式的缺陷。如果集体中的每个人的账单信息只能被Boss一个人所拥有,而集体中的其余每个人想要知道自己的账单,就需要去找Boss,从他这里获取信息,这是唯一的信息来源。如果这是个黑心的Boss,他私自修改你的账单,想让你多掏钱,而你并无法得知,或者是他修改自己的账单,想让自己少掏钱,你也无法得知。而分布式则是将这个账单公开,集体中的每个人手里都有所有人的账单,这时不再有Boss和普通人的区别,所有人都一样,每个人都有自己和其他人的账单。这样就能很好地相互监督,共同去维护这一份所有人的账单。

 

理解Git的分布式版本控制

大部分人心目中的分布式的概念可能更多来自于分布式计算。分布式计算使得程序可以通过某种机制分布地运行在多台计算机上从而最大化地利用多台计算机的计算能力、存储能力。分布式计算是将计算任务分割成多个可以独立运行的子任务,然后将子任务分布在多台计算机独立并行运行,最后通过某种合并机制将所有计算机的计算结果最终合并起来。因此单独来看这多台计算机中其中某一台,它并没有拥有程序的所有数据和所需资源。从表面看这似乎和分布式版本控制系统中的分布式概念截然相反。毕竟分布式版本控制系统"号称"克隆一次代码库本地就拥有了一个完整的代码库副本,这听起来有些骇人听闻。

其实我们可以尝试从以下两个方面来理解:

  1. 在分布式版本控制系统中,克隆了代码库的各本地开发者拥有了服务器分发过来(Distributed)的完整的代码库副本,使得开发者们可以独立于主服务器之外进行开发任务,这和分布式计算概念中,各计算机独立进行计算任务的理念不谋而合。同时也符合分布式存储的理念:一个文件多份副本。
  2. 各开发者在完成开发任务后又需要将自己本地修改后的代码库合并Merge到主服务器上。这也与分布式计算概念中最终需要将各计算机的计算结果合并起来的概念是相符的。