01-版本管理系统的概念
很多人认为 Git 难以理解的第一个门槛在于所谓的「Git 是一个分布式版本控制系统」这句话的具体含义不够清楚。其实分布式版本控制系统Distributed Version Control System - DVCS这个定义并不难不过一步一步来我先告诉你什么是版本控制系统Version Control System - VCS。版本控制最基本功能版本控制系统VCS最基本的功能是版本控制。所谓版本控制意思就是在文件的修改历程中保留修改历史让你可以方便地撤销之前对文件的修改操作。最简化的版本控制模型是大多数主流文本编辑器都有的「撤销Undo」功能你本来想删除一个字符却在按删除键之前不小心选中了全文结果一下子整篇文档都被删光了没关系按一下「撤销」Ctrl Z 或 ⌘ Z 或 U 等等具体和你的操作系统以及编辑器有关删掉的文字就都回来了。这其实是文本编辑器帮你自动保存了之前的内容当你按下「撤销」的时候它就帮你把内容回退到上一个状态同理按一次是会退到上一个版本按两次就是回退到上上一个版本。写程序的时候同样也难免会遇到「写错」的情况所以程序的 VCS当然也会需要版本控制功能这样当你发现「昨天有一行代码写错了」你就不用凭着记忆把那段代码背出来而只需要在 VCS 中选择撤回到昨天的那个版本。主动提交程序代码和普通文本的区别VCS 和文本编辑器的撤销功能比起来有一个很重要的区别是程序代码的修改的生命周期非常长。一次代码的修改在几天后、几个月后、几年后都有可能需要被翻出来。如果依然采用「每次改动自动保存」的形式来保留修改历史将会导致改动历史非常频繁和无章可循这样历史代码的查找、阅读和回退就会很困难了。所以和文本编辑器的撤销功能不同VCS 保存修改历史使用的是主动提交改动的机制。在你写了一段完整的代码例如修复了一个 bug之后使用 commit 命令把改动和对改动的描述信息提交这次改动就被记录到版本历史中了。之后如果你希望回退到这个版本就可以从 VCS 的历史日志中方便地找到它。多人合作的同步需求中央仓库代码可以一个人写但更多的时候会是多个人共同开发。那么自然地就需要有一个中央仓库作为代码的存储中心所有人的改动都会上传到这里所有人都能也都能看到和下载到别人上传的改动。这样解决了同步的需求多个人在不同的机器上开发同一个程序就成了可能。版本控制、主动提交、中央仓库这三个要素共同构成了版本控制系统VCS的核心开发团队中的每个人向中央仓库主动提交自己的改动和同步别人的改动并在需要的时候查看和操作历史版本这就是版本控制系统。中央式版本控制系统最初的版本控制系统是中央式版本控制系统Centralized VCS也就是前面我讲的这种。Git 是分布式的版本控制系统Distributed VCS它和中央式的区别我在下节说现在先说一下中央式版本控制系统的工作模型。工作模型假设你在一个三人团队你们计划开发一个软件或者系统并决定使用中央式 VCS 来管理代码。于是作为项目的主工程师你独自一人花两天时间搭建了项目的框架然后你在公司的服务器这个服务器可以是公司内的设备也可以是你们买的云服务上创建了一个中央仓库并把你的代码提交到了中央仓库上你的两个队友从中央仓库取到了你的初始代码从此刻开始你们三人开始并行开发在之后的开发过程中你们三人为了工作方便总是每人独立负责开发一个功能在这个功能开发完成后这个人就把他的这些新代码提交到中央仓库每次当有人把代码提交到中央仓库的时候另外两个人就可以选择把这些代码同步到自己的机器上保持自己的本地代码总是最新的。而对于团队中的每个人来说就会更简单一点第一次加入团队时把中央仓库的代码取下来写完的新功能提交到中央仓库同事提交到中央仓库的新代码及时同步下来。这样一个三人的团队就成功做到了各自在自己的电脑上开发同一个项目并且互不影响就好像你们三个人是在同一台电脑上操作一样。这就是中央式 VCS 最基本的工作模型。当然实际的开发工作并没有简单到这种程度因为你时常会需要处理代码冲突、查看版本历史、回退代码版本等另外Git 属于分布式 VCS它的概念也比中央式 VCS 要复杂一些。但这些概念你需要一步步地理解和吸收你现在只需要先知道中央式 VCS 的这个基本工作模型其他的内容我会在后面慢慢地全部讲清楚。什么是分布式版本控制系统DVCS分布式 VCS Distributed VCS / DVCS和中央式的区别在于分布式 VCS 除了中央仓库之外还有本地仓库团队中每一个成员的机器上都有一份本地仓库这个仓库里包含了所有的版本历史或者换句话说每个人在自己的机器上就可以提交代码、查看历史而无需联网和中央仓库交互——当然取而代之的你需要和本地仓库交互。中央式 VCS 的中央仓库有两个主要功能保存版本历史、同步团队代码。而在分布式 VCS 中保存版本历史的工作转交到了每个团队成员的本地仓库中中央仓库就只剩下了同步团队代码这一个主要任务。它的中央仓库依然也保存了历史版本但这份历史版本更多的是作为团队间的同步中转站。工作模型依然以三人团队为例分布式 VCS 的工作模型大致是这样首先你作为主工程师独立搭建了项目架构并把这些代码提交到了本地仓库然后你在服务器上创建了一个中央仓库并把 1 中的提交从本地仓库推送到了服务器的中央仓库其他同事把中央仓库的所有内容克隆到本地拥有了各自的本地仓库从此刻开始你们三人开始并行开发在之后的开发过程中你们三人总是每人独立负责开发一个功能在这个功能开发过程中一个人会把它的每一步改动提交到本地仓库。注意由于本地提交无需立即上传到中央仓库所以每一步提交不必是一个完整功能而可以是功能中的一个步骤或块。在一个人把某个功能开发完成之后他就可以把这个功能相关的所有提交从本地仓库推送到中央仓库每次当有人把新的提交推送到中央仓库的时候另外两个人就可以选择把这些提交同步到自己的机器上并把它们和自己的本地代码合并。可以看出这个工作模型和上一节讲的「中央式 VCS 的工作模型」很相似只是把代码的提交和上传过程拆开了。另外和上节讲的中央式 VCS 工作模型一样这个也只是分布式 VCS 的一个最基本的工作模型实际的开发工作会比这个麻烦和复杂。但这是个核心模型你把它理解了就可以更好地看懂后面的内容。优点与缺点分布式 VCS 的优点大多数的操作可以在本地进行所以速度更快而且由于无需联网所以即使不在公司甚至没有在联网你也可以提交代码、查看历史从而极大地减小了开发者的网络条件和物理位置的限制例如你可以在飞机上提交代码、切换分支等等由于可以提交到本地所以你可以分步提交代码把代码提交做得更细而不是一个提交包含很多代码难以 review 也难以回溯。分布式 VCS 的缺点由于每一个机器都有完整的本地仓库所以初次获取项目Git 术语clone的时候会比较耗时由于每个机器都有完整的本地仓库所以本地占用的存储比中央式 VCS 要高。对于一般的程序项目而言由于项目的大多数内容都是文本形式的代码所以工程的体积都并不是很大再加上文本内容自身的特点VCS 可以利用算法来把仓库的体积极大地压缩。这就导致在实际中Git 等分布式 VCS 的仓库体积并不大初次获取项目的耗时和本地仓库的存储占用都很小。所以对于大多数的程序项目而言分布式 VCS 「尺寸大、初次下载慢」的问题其实并不严重。不过也有一些例外比如游戏开发。游戏的开发中有大量的大尺寸数据和媒体文件并且这些文件的格式也不容易压缩尺寸如果用分布式 VCS 会导致仓库的体积非常庞大。所以一些大型游戏的开发会选择中央式的 VCS 来管理代码。