vcs是什么软件(VCS技术演进从SCCS到Git)
爱跨境 跨境电商 2022-06-20 11:47:03 · 热度999

当今IT界,VCS版本控制系统的的使用已经成了一种日常不可或缺部分。不光是程序员、IT界甚至在其他领域也是逐渐了有了共识。通过Github写书也不再是天方夜谭或者技术段子,而是实实在在天天发生的事情。本文,我们来一起回顾下历史上主要版本控制系统(VCS)的发展过程,涉及了内容有:SCSS、RCS、CVS、SVN,Git和Mercurial。

概述

回顾VCS的发展历程,总体上可以划分为三个阶段。

第一代VCS,包括SCSS和RCS。立足于对单个文件变化的跟踪,检出的文件一次只能由一个用户在本地进行编辑,用户通过自己的帐户登录到同一共享Unix主机方式实现。

第二代VCS,包括CVS和SVN。通过引入网络,从而形成了包含正式意义上的项目版本的集中式版本存储库。相比第一代VSC,有了实质性的发展,可以供多个用户同时检出并使用代码,但是他们都需要重新提交到同一中央存储库。存在的问题是严重依赖于中央存储库,对网络和实时性同步要求很大。

第三代VSC,包括Git和Mercurial。V到现在发展成为了分布式VCS。在分布式VCS中,创建存储库的所有副本都是相同的,无需一个集中的中央存储库。无需通过网络实时同步内容,只需本地创建提交,分支和合并打开了路径,在合适时候再推送到远端库。

VCS重要软件发展历史时间表:

vcs是什么软件(VCS技术演进从SCCS到Git)

SCCS第一代版本管理系统

SCCS(Source Code Control System)是最早创建的VCS工具。它由贝尔实验室的Marc Rochkind于1972年用C开发。SCCS旨在解决源文件修订跟踪的问题。此外,它还解决程序bug错误定位的问题。SCCS是现代VCS的鼻祖,至此后VCS发展30年到现在茁壮发展。

vcs是什么软件(VCS技术演进从SCCS到Git)

功能

和大多数现代的VCS一样,SCCS支持一组命令,供开发人员做文件版本控制。主要实现的功能有:

检入文件以使用SCCS跟踪其历史记录;

检出特定的文件修订以供审核或编译;

检出特定的文件修订以进行编辑;

检入新文件修订以及说明更改的注释;

还原检出文件中所做的更改;

基本分支和变更合并;

提供文件修订历史记录。

技术实现

当添加文件到SCCS进行跟踪时,会创建一种称为s文件或历史文件特殊类型的文件。该文件使用以s开头的原始文件名来命名,存储在名为SCCS的子目录中。比如,一个名为test.txt的源文件将在./SCCS/目录中创建一个名为s.test.txt的历史文件。创建后,历史记录文件将包含原始文件的初始内容以及一些元数据以帮助进行版本跟踪。文件校验和存储在历史记录文件中,以验证内容是否遭到篡改。历史记录文件的内容未经过压缩或编码。由于原始文件的内容存储在历史记录文件中,因此可以将检出到到工作目录进行查看,编译或编辑。可以将对文件所做的进一步更改(例如,行添加,修改和删除)检入到历史文件中,并增加修订号。

SCCS检入仅存储增量或文件更改,而不是每次存储整个文件内容。这样可以减小历史记录文件的大小。每次检入时,增量都存储在历史记录文件内部的称为增量表的结构中。如前所述,实际文件内容或多或少是逐字复制的,带有特殊的控制序列,用于标记已添加和已删除内容的各个部分的开头和结尾。由于SCCS历史记录文件不使用压缩,因此它们通常比要跟踪的实际文件大。

SCCS使用一种称为交错增量的增量方法,支持恒定时间检出,而不管检出的修订版有多老。即较旧的修订版检出所花费的时间不会比新的修订版更长。

需要注意的重要一件事是,所有文件都在SCCS中被单独跟踪和检入。没有办法将更改作为一个原子单位的一部分检入多个文件(和Git提交一样)。每个跟踪的文件都有一个对应的历史文件,用于存储其修订历史。

当检出文件以在SCCS中进行编辑时,为了防止更改被其他用户覆盖,文件上将放置一个锁,但是这会限制多用户的编辑从而开发效率。

SCCS支持可以在特定文件内存储更改序列的分支。分支可以与原始版本合并回去,也可以与同一父级的其他分支版本合并。

基本命令

以下是最常见的SCCS命令的列表。

sccs create <filename.ext>:将新文件检入SCCS并为其创建新的历史记录文件(默认在./SCCS/目录中)。

sccs get <filename.ext>:从相应的历史文件中检出文件,并以只读模式将其放置在工作目录中。

sccs edit <filename.ext>:从相应的历史文件中检出文件进行编辑。锁定历史记录文件,以便其他用户无法修改它。

sccs delta <filename.ext>:检入对指定文件的修改。将提示填写commit,将更改存储在历史记录文件中,然后删除锁。

sccs prt <filename.ext>:显示跟踪文件的修订日志。

sccs diffs <filename.ext>:显示文件的当前工作副本与检出时文件状态之间的差异。

版本文件

一个SCCS历史记录文件示例:

vcs是什么软件(VCS技术演进从SCCS到Git)

RCS版本管理系统

RCS(Revision Control System)由Walter Tichy于1982年用C编写,用以替代SCCS,SCCS当时还不是开源的。

vcs是什么软件(VCS技术演进从SCCS到Git)

功能

RCS与它的前任SCCS有许多共同之处,包括:

逐个文件处理修订;

跨多个文件的更改不能一起归类为原子提交;

跟踪文件旨在一次由一个用户修改;

没有网络功能;

每个跟踪文件的修订都存储在相应的历史文件中;

基本分支和修订在单个文件中的合并。

技术实现

当将文件检入RCS时,会在当前目录下的./RCS/目录中创建相应的历史文件。该文件后缀有.v,比如,test.txt的文件将将创建test.txt.v的跟踪文件。

RCS使用反向增量方案来存储文件更改。检入文件后,文件内容的完整快照将存储在历史记录文件中。修改文件并再次检入后,将根据现有历史文件内容计算增量。旧的快照将被丢弃,新的快照将被保存,并与增量一起恢复到较早的状态。之所以称为反向增量,是因为要检出旧版本,RCS需要从文件的最新版本开始并应用连续的增量,直到达到旧版本为止。由于始终可以使用当前修订的完整快照,因此该方法可以非常快速地检出当前修改。但是,检出版本越老,检出花费的时间越长,因为需要针对当前快照计算越来越多的增量。

相比较SCCS花费相同的时间来获取任何修改。RCS历史记录文件中没有存储校验和,因此无法确保文件完整性。

基本命令

以下是最常见的RCS命令的列表:

ci <filename.ext>:将一个新文件检入RCS并为其创建一个新的历史记录文件(默认在./RCS/目录中)。

co <filename.ext>:从相应的历史文件中检出文件,并以只读模式将其放置在工作目录中。

co -l <​​filename.ext>:从相应的历史文件中检出文件以进行编辑。锁定历史记录文件,以便其他用户无法修改它。

ci <filename.ext>:检入文件更改并在其对应的历史文件中为其创建一个新修订。

merge <file-to-merge-into.ext> <parent.ext> <file-to-merge-from.ext>:合并更改来自同一父文件的两个修改后的子对象。

rcsdiff <filename.ext>:显示文件的当前工作副本与检出时文件状态之间的差异。

rcsclean:删除没有锁的工作文件。

RCS更多操作介绍,详见GNU RCS说明手册。

版本文件

RCS .v历史记录文件样例

vcs是什么软件(VCS技术演进从SCCS到Git)

CVS第二代版本管理系统

CVS(Concurrent Versions System)由Dick Grune于1986年创建,主要是在第一代单机版本控制工具基础上添加了网络,使其网络化协作化。CVS也是用C语言编写的。CVS开启了VCS发展的第二个里程碑,开启了第二代VCS工具的发展。CVS的网络化使地理上分散的开发团队可以协同开发。

vcs是什么软件(VCS技术演进从SCCS到Git)

功能

CVS采用C/S架构体系,其代码都都存储在服务器端,开发者需从服务器上获得一份代码复制到本机,然后开发。开发者可随时将新代码提交给服务器,也可以通过更新操作获得最新的代码,保持与其他开发者的一致。CVS提供了一组用于与项目中的文件进行交互的命令,但是使用RCS历史文件格式和后台命令。

VCS历史上,CVS首次允许多个开发人员检出并同时处理相同的文件。CVS在处理多人同时修改页面时,采用"先允许修改,再处理冲突"。

检出:用来下载文件和建立服务器和本机目录之间的对应关系。不会修改本机已有文件的"只读"属性;

Export输出:用来下载服务器文件到本机,从而进行软件的编译发布;

更新:用于获取当前最新版本,也可以用于获取某个特定版本;

Edit编辑:仅用来通知服务器,要编辑某个文件。

unedit:仅用来通知服务器,完成某个文件的编辑了,同时将本机文件置为"只读";

Watch:实现监视协作者edit文件状态的情况,要实现这种监控,要求所有人在自己本机修改文件之前,都edit一下,并在commit之后,unedit一下,别人才能收到通知;

Commit:类似于检入,不同的是,其不修改本机文件的"只读"属性,commit后你仍然可以继续修改本机文件,必须unedit后文件属性才改完"只读"。

技术实现

CVS通过使用集中式存储库模型,第一步是使用CVS在远程服务器上建立集中式存储库。然后就可以将项目导入到存储库中,将项目导入CVS后,每个文件都被转化为.v历史文件,并存储在被称为模块的中央目录中。该存储库通常位于可通过本地网络或Internet访问的远程服务器上。

开发人员通过检出该模块的副本,并复制到本地工作目录中。在此过程中不会文件被锁定,因此可以同时无限制的进行文件检出。开发人员可以修改检出的文件并根据需要提交更改。如果开发人员要提交更改,则其他开发人员将需要在提交更改之前先通过自动合并过程更新其工作副本。必要时候,需要先解决合并冲突。 CVS还提供了创建和合并分支的功能。

基本命令

export CVSROOT=<path/to/repository>:设置CVS存储库根目录,无需在每个命令中都指定它。

cvs import -m 'Import module' <module-name> <vendor-tag> <release-tag>:将文件目录导入CVS模块。

cvs checkout <module-name>:将模块复制到工作目录。

cvs commit <filename.ext>:将更改的文件提交回模块。

cvs add <filename.txt>:添加一个新文件以跟踪修订。

cvs update:通过合并远程存储库中存在的已提交更改而不是工作副本来更新工作目录。

cvs status:显示有关已检出模块工作副本的常规信息。

cvs tag <tag-name> <files>:将识别标记添加到单个文件或一组文件中。

cvs tag -b <new-branch-name>:在存储库中创建一个新分支(必须先检出,然后在本地进行操作)。

cvs checkout -r <branch-name>:将现有分支检出到工作目录。

cvs update -j <branch-to-merge>:将现有分支合并到本地工作副本中。

更多CVS操作,详见GNU CVS手册。

版本文件

CVS历史记录文件示例:

vcs是什么软件(VCS技术演进从SCCS到Git)

SVN,集大成者

Subversion由Collabnet公司在2000年创建,后交由Apache 软件基金会维护。SVN也是用C编写的,用于改善CVS,实现更强大的集中式解决方案。时至当下,仍有大量的公司依赖于SVN实现其项目管理。

vcs是什么软件(VCS技术演进从SCCS到Git)

技术实现

和CVS一样,SVN也使用集中式存储库模型。远程用户必须依赖网络来实现连接才能将其更改提交到中央存储库。

Subversion引入了原子提交的功能,确保提交将完全成功,或者在发生问题时被完全放弃。在CVS中,如果提交操作中途失败(例如,由于网络中断),则存储库可能损坏和不一致的状态。

Subversion中的提交或修订可以包含多个文件和目录。这样可以允许用户以项目为单位的跟踪相关更改集,而无需分别跟踪每个文件的更改。

Subversion用于跟踪文件的存储模型称为FSFS(File System atop the File System),使用与运行的操作系统文件系统相匹配的文件和目录结构来创建其数据库结构。Subversion文件系统的独特之处在于,它不仅可以跟踪其包含的文件和目录,还可以跟踪这些文件和目录的不同版本,并且它们会随着时间变化。它是一个具有附加时间维度的文件系统。

Subversion以文件夹为基本管理单位。可以在Subversion中提交空文件夹,而在其它(甚至是Git)VCS中,无法管理空文件夹。

创建Subversion存储库后,将创建一个空的文件和文件夹数据库作为其一部分。将创建一个名为db/revs的目录,其中存储了已检入(已提交)文件的所有修订跟踪信息。每次提交(可以包括对多个文件的更改)都存储在revs目录中的新文件中,并以从1开始的顺序数字标识符命名。当首次提交文件时,将存储其全部内容。为了节省空间,同一文件的在次提交时候将仅存储变化部分,也称为diffs或deltas。