Version Control Systems

版本控制系统简介RCS/CVS/Subversion/

 

    一个版本控制系统最基本的功能就是记录每次修改的地方,并且可以让使用者方便地存取各个版本、比较版本差异。更进一步的,是建立一个多人开发的环境,可以计录每个人的修改,解决版本冲突的问题。版本冲突问题是指两个人同时对一个档案作修改的动作,举个例子说,现在数据库里的版本是A,甲和乙分别把这两个档案拿出来(这个动作通常叫 checkout),在做了一番修改之后,甲先把改变的数据存回去(这个动作通常叫 checkin),这时问题还没有发生,数据库的板本被更新成B,但是当乙 checkin 的时候,问题就来了,乙的版本也是从 A 修改而来的,到底该用甲的修改版还是乙的呢?如果硬把甲的修改用乙的版本盖过去,那甲所花的工夫就全部白费了。最常用的解决办法是用文件按锁定的功能,就是当甲在修改某个档案的时候,会把档案加个 lock flag 让大家知道,这个档案正在被修改,不要去动它。不过像 CVS等进阶的版本控制系统,就算没有做档案锁定的动作,发生版本冲突时,也提功了方便的功能可以把两个版本 merge起来。
       目前有许多商业与开放源码的版本控制系统. 在开放源码界, 最早出现的, 大概就是 SCCS, 其后演变成为 RCS. 这两个都是以个别档案为基础来进行版本控制. 后来就有了 CVS 的出现, 它架构在 RCS 之上, 并且可以处理多个档案的送交 (也就是跟版本控制软件说, 我有这些档案更动过了, 请记住这些更动).

[RCSRevision Control System]
一个相当相当古老的工具了,虽然现在大家都是用 CVS 来做版本控制的工具但是如果没有可以使用的 CVS server 那就没有办法使用了,RCS 主要是偏个人使用的,没有像 CVS 有许多强大的功能,也不支持远程档案系统的存取。
     但是在只需要单纯的版本管理功能时,就相当的有用了。建议大家如果在工作站上写程序,或是写文件的时后,可以试着用 RCS 来做版本管理的工作,一开始可能会觉得绑手绑脚的,但是用久了,你一定会发现使用版本控制系统真是好处多多!
     使用 RCS 相当简单,只有几个指令而已,大部份系统都有包含。
     简单的使用方法就是这样:

1.
建立 RCS 数据库
先在想要保存的程序代码下的目录下建立一个叫 RCS 的目录
mkdir RCS
2.
将档案登入到RCS 数据库
ci filename
这时,RCS 会要你输入 log,就是记录你对这个版本有什么说名的地方,简单说几句就可以了,当然也可以不打,然后会给你一个初始的版本编号,应该是1.1。你会发现到,原来的档案不见了,而在 RCS 目录下多了一个叫做 filename,v 的档案,那个档案就是用来记录 filename 的版本演进史的。
3. 把档案取出来
档案不见了,那还有什么戏唱,能够放进去的,当然就一定可以拿出来:
最基本的用法是这样,会取出 filename 的最新版本。
co filename
但是,注意它的属性,是只读的喔,要加上 -l 的参数表示要 lock 才可以做修改的动作,修改完了,再把档案 checkin 回去就完成了版本更新的动作了,这时的版本编号应该是1.2
另外,co -r filename可以取出指定的版本,但是其属性一定是只读的。
4. 把修改的档案存回RCS 数据库
还是一样,ci filename,不过可以加上 –u 的参数顺便 unlock,如果要继续编辑的话,要加上 –l ,不然会自动把原来目录下的档案删除。
5. 观看一个档案的修改记录
rlog filename
比较版本的差异
rcsdiff -r[version] filename
大概的使用方法就是这么简单,有了基本版本控制系统的概念之后,要使用 CVSSubversion 等进阶的版本控制系统,就相当容易了。

[CVSConcurrent Versions System]
CVS
是继RCS等传统的维护工具之后,新一代的程序开发与维护系统,现在网络上许许多多的 Open Source Project,几乎都是使用 CVS 来做版本控制的工具,它拥有以下的特色:
程序代码版本的储存与维护
程序代码版本的追踪回溯
程序代码版本的分合控制
支持多人合作开发项目
程序代码远程管理维护
程序代码匿名截取
    另外,CVSup CVS 是两个不一样的东西,前者大都是方便使用者可以取得与开发者同步程序代码所的工具,它是透过比对 server/client 之间的 source code cvs id table 来判断那些档案需要修改,在速度上有很大的优势。另外还有一项使用 CVSup 的优点是它可以在你的本地机器上复制整个 CVS repository,允许快速的本地使用 cvs 操作,像 log diff
    CVS 是给开发人员用的。不过许多 Open Source Project 都会提供 anonymous CVS,通常只有 read 的权限。给其它使用者取得他们所想要的版本,主要的作用就是把最新开发的程序代码给喜欢新鲜货的人,让大家一起来测试,对一个 project 的开发,相当有帮助。
CVS 也不支持档案更名. 也就是说, 如果我们想要变更某个档案的名称, 那么它以前所累樍的更动与批注就得丢弃. 它也不支持以目录为单位的变动, 所以要想回复某个时间的目录内容是不可能的
.
  另外,介绍一些好用的GUICVS界面
    WinCVSwin32环境下的,不过笔者觉得相当难用。
    CervisiaKDECVS GUI界面,可以和Konqueror整合,使用上感觉相当亲切。

[Subversion]
一套更好的 CVS! 它同样也是开放源码, 而且架构, 命令列程序界面等, 都刻意模仿 CVS, 为的就是要让习于 CVS 的使用者能够快速上手
.
  目录版本控制
  在 CVS , 一个目录是没有版本历程的. 假如原本一个名为 doc/ 的目录, 在经过一段时间之后, 发现它应该要称为 manual/ 比较恰当, 此时我们只能建立一个新 manual/, doc/ 目录下的档案复制过去, manual/ 下的档案新增至 CVS 系统中, 再把 doc/ 删除. 而且必须注意的是, 在档案的复制与删除的过程当中, 我们也同样地遗失了这些档案的历史历程. 版本控制最主要的数据就这么丢掉了
!
  但是在 Subversion , 目录跟档案同样都是纳入版本控制之中. 也就是说, 我们可以随时要求 Subversion 将某个档案回复到某个时间点的状态, 也可以对目录进行更名的动作
.
  不可分割的送交
  在 CVS , 虽然我们可同时对复数档案进行送交, 但是 CVS 并不保证一次的送交是不可分割的. 也就是说, 如果我们同时对三个档案进行送交, 但是在第二个档案时发生意外状况 (例如档案有冲突, 或是网络断线), 此时 CVS 系统中会有送来的第一个档案的更动, 但是没有第二个与第三个的. CVS 系统里的档案就变成一个与我们预期不一致的状况
!
Subversion
的送交就没有上述的问题. 也就是说, 送交的结果, 不是全都进系统, 就是全都没有进系统, 不会只有一部份进系统的状况
.
  更佳的二进制数据处理
  CVS 虽然号称可以处理二进制的数据 (例如图形文件, Microsoft Word 档案), 但是需要使用者特别设定, 而使用者 常常忘记. 再加上 CVS 会主动更动档案内容, 如列尾符号与关键词展开的功能, 以至于常常在需要将档案回复至过去的状况时, 才发现档案变得无法读取了. 再者, CVS 的档案内容差异算法几乎无法处理二进制档案, 以致于在储存档案上
,
需要耗费大量的空间
.
  Subversion 对上述问题的处理方法有二. 首先, 它不主动更动档案内容, 除非使用者加上这样的设定. 再者, 它使用可适用于文字与二进制数据的内容差异算法, 在档案储存上, 文字与二进制数据都具有相同的优势. 现在, 不只是文字数据适合置于版本控制系统中, 连二进制数据也可以很方便地放进来
.
  高效率的分支与标记
   我们可以对已纳入版本控制系统的档案进行标记, 也就是赋与它们一个易记的文字, 日后便可以利用这个易记的文字, 将这些档案回复到某个特定的状态. 但是 CVS 必须对每一个档案加上这样的标记, 档案愈多, 耗时愈久
.
  在 Subversion 系统, 标记是以目录的副本的方式建立的, 而副本是以类似链接的方式来建立. 也就是说, 不管牵涉的目录与档案有多少, 它所花费的时间都是固定的, 不会因为档案愈多而耗时愈久
.
  CVS 最为人所垢病的缺点, 就是它的分支功能相当难以使用. 但是在实际上运用时, 分支功能可以为使用人员增加不少便利. 像是可以藉由使用分支, 将程序代码隔离开来, 让发展人员可以进行大规模更动的同时, 还能让维护人员进行维护. Subversion 的分支, 亦是以目录的副本来实作的, 在观念上更容易学习, 使用起来也更方便
.
  Subversion 的缺点
  但是 Subversion 亦不全然没有缺点, 它毕章还是一个刚开始发展的系统, 仍然存在一些不易使用的地方
.
  档案保留
  我们无法取得 Subversion 档案的独占编辑权. 这是因为 Subversion 的工作模式, 是让各个工作的人取得工作复本, 各自编辑后, 再于送交时进行合并. 不过有的时候, 我们还是得要先取得档案的独占编辑权, 像是在编辑图形文件. 此时, 由一个人统一对某个档案进行编辑, 要比事后合并要简单地多了
.
  合并点
  当一个项目开始产生分支时, 常常我们得先将目前分支的更动合并至主发展线, 这些被合并的更动, 就称为合并点. Subversion 并不会记住分支已经采用了哪些合并点, 也就是说, 如果在合并更动之后, 在合并的地方又有了更动, 日后当分支发展完毕, 整个分支的更动需要合并至主发展线时, 由于系统不会记得已采用了哪些更动, 而已合并的地方又更动过, 就会造成同一个更动被合并两次, 此时后来的更动几乎可以肯定会造成档案的冲突, 必须由使用者进行排解. 如果系统能够记得合并点的话, 已采用的合并点就毋需再采用, 也就可以减少使用者必须手动进行冲突排解的次数
.
档案版本
  在 Subversion , 版本号码是整个系统共享的. 这个意思就是说, 如果一个项目的档案因修改而有版号的更动, 那么所有档案的版号都会跟着更动. 这对由 CVS 移转过来的使用者是最难以接受的, 需要花一点时间习惯
.
  但是, 在这种全域版号下, 我们无法很简单地回答这样的问题: 某个档案的第一个版本长什么样? 在目前最新版的前两个版本作了什么更动? 你知道, 有些时候, 我们就是需要像这样的功能
.
  
I18N, L10N
  虽然 Subversion 本身架构支持 Unicode, 不过使用者界面还是使用纯英文的环境. 对于多国语言的支持仍有一段路途要走
.

[结语]
  以上简单介绍了 Subversion CVS 的优缺点评比. 虽然 Subversion 才开始发展三年, 直到今年才进入 1.0 , 但是它所提供的便利性与功能性, 已经凌驾于 CVS 之上. 目前尚有不足的功能, 在活跃的开发团队的手中, 必定能很快地加上去. 有兴趣的读者现在就赶快加入使用 Subversion 的行列吧
!
  一个全新的版本控制系统,企图取代 CVS,提供了比 CVS 更佳的版本管理功能。

Advertisements