集中式版本控制与分布式版本控制——Git 学习笔记01

什么是版本控制

如果你用 Microsoft Word 写过东西,那你八成会有这样的经历:

想删除一段文字,又怕将来这段文字有用,怎么办呢?有一个办法,先把当前文件“另存为”一个文件,然后继续改,改到某个程度,再“另存为”一个文件。就这样改着、存着……最后你的 Word 文档变成了这样:

这里写图片描述

过了几天,你想找回被删除的文字,但是已经记不清保存在哪个文件了,只能挨个去找。真麻烦,眼睛都花了。看着一堆乱七八糟的文件,真想把不用的都删除,只保留一个终极版,可是又怕哪天会用上,还不敢删,真愁人。

这时候你想,要是有一个软件能帮你记录每一个版本,并且能显示出各个版本之间的差异,那多方便啊。幸运的是,这样的软件还真有,git 就是其中一个。

git 不仅具备记录版本、比较差异等最基本的功能,还支持分支、离线开发、多点开发…… 总之 git 有非常丰富而强大的功能等着你去学习与发现。如果说你学习 git 是为了收获一缕春风,那么最后你得到的将是整个春天。

集中式版本控制(Centralized Version Control )

开发者之间的合作方式是共用一个仓库(repository),无论这个仓库是在本地还是在远端,只要是所有成员都共同存取同一个仓库,那么这种方式就是集中式(centralized)版本控制。

集中式版本控制的特点

集中式的版本控制系统其实有三大重点,即同步、追溯、以及档案的备份。
同步是为了让所有开发者对档案所做的变更都能够同步,最终得到相同的档案内容。

而追溯,则是能够回到受控档案在变化历史中的任何一个版本,并且明白每个版本间变化的原因、以及究竟做了什么变动。

至于档案的备份,无庸置疑的,就是让所有的受控档案集中保管于仓库中,作为备份也利于备份。不但能取得最新的版本,也能够取出任意时间点上的版本。

所以说,从集中式版本控制系统的设计观点来看,它主要是维持开发者之间保持同步的状态。若是根据保持同步的手段再细分,又能衍生出两种模式:一种是锁定模式,另一种是合并模式。

在锁定模式下,当开发者想要修改某档案、签出该档案后,该档案便会进入锁定状态,其他开发成员便无法加以修改,直到签出者将该档案签回为止。对于维持同步来说,这当然是一个十分保险的作法,因为永远不会有两个或以上的开发者同时修改同一个档案。只是这种方法造成了开发者对于档案修改的互斥效应,大大降低了开发效率。

因此,许多版本控制系统采用合并模式,在合并模式下,允许多位开发者同时针对同一档案进行修改,当他们分别将档案提交回仓库时,若发生冲突的情况,便会自动进行合并,而若自动合并失败,再要求人工合并。不过即使如此,最终目的还是要维持多个开发者间的同步。毕竟,版本控制的结果在集中式档案库中是唯一的,也是每位开发者都需与此结果保持一致的。

集中式版本控制的缺点

集中式版本控制系统使用起来会有什么问题呢?

首先,开发者想要签出代码、提交到仓库,或是对档案库做一些其他的操作,都必须在能够连网的环境下进行。这会大大降低开发效率。例如,你已经在本地端做好了必要的修改,想要提交到系统上,却因为正处于无法连网的环境,所以无法将档案提交出去。

当然,或许你会想,可以等到能联网之后再提交就好了。但是,我们希望每次提交的变更都是一个不可分割的最小单位,若因无法连网,无法将已完成的修改提交出去,那么也就无法继续修改其他的项目,不然应该被分为多次提交的内容就混在一块了。

如果有的开发者处在一些连网环境、速度较不佳的地区,每次存取仓库中的数据都会耗去大量的时间,这也是非常有碍效率的。

再者,由于每个开发者的修改,时常是反复持续进行,在修改的过程中,总会遇到未能稳定、完备到足以提供其他开发者使用的程度,若是在此时提交到仓库,便有可能让仓库的代码处于不稳定、不成熟的状态。当然,也可以让开发者持续修改至足够稳定完备后,再将修改内容提交至仓库。但是,在这个空窗期里,开发者就无法享受到版本控制的好处,他没有办法将修改过程中的不同阶段,划分成为多个版本。

分布式版本控制(Distributed Version Control)

由于集中式版本控制系统有一些致命的缺点,分布式(或分散式)版本控制系统应运而生,甚至慢慢成为主流。

分散式版本控制系统和集中式版本控制系统,其最大差别在于前者的仓库可以有多份。事实上,每个开发者都可以在自己的一台或者多台电脑上建立档案库。

虽然你可能认为二者都是将受控的档案储存在本地端,但其实档案库档案在本地端的工作复本还是有很大差别的。其中最重要的意义在于档案库中包含了完整的版本管理数据、例如提交信息、版本变化记录等等。因此,所有对版本控制系统的操作,都可以直接在本机端的档案库中进行,包括提交、分支、合并、回退等。

对分散式版本控制系统来说,其核心不在于维持不同开发者间的同步,而在于让每个开发者拥有各自独立的变更集合,且开发者之间可分享自己的变更集合。

在分散式版本控制系统中,开发者可以进行“推”(push)的动作,其意义是将自身档案库中的变更送至其他的档案库;也可以进行“拉”(pull)的动作,其意义是获取其他档案库的变更。

因为每个开发者都拥有独立的档案库,所以可以直接对自己的档案库进行操作。在离线环境中,开发者既可以连续工作,也可以持续修改,和本地档案库进行交互(比如管理版本、查询修改历史、回溯、提交、……)。另一方面,开发者不需要将自己的修改持续送至集中的档案库上,造成其他开发者必须套用这些修改,引起可能的不稳定情况。

因为分散式版本控制系统本质的关系,使得此类系统更重视对分支(branch)的支持,它们通常有较好的分支及合并的能力。git 非常提倡我们利用分支来辅助日常工作流程。

有了分散式的档案库及强大的分支管理,因而衍生出多种工作流程,比如集中式(Centralized)、整合管理者式(Integration-Manager)、司令官及副官式(Dictator and Lieutenants)等等。


参考资料

[1] https://www.ithome.com.tw/node/77088
[2] https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

猜你喜欢

转载自blog.csdn.net/u013490896/article/details/81153530