CVS

CVS是什么?


CVS是一个版本控制系统。使用它,你可以记录下你的源文件的历史。 

例如:修改软件时可能会产生一些bug,而且可能过了很久你才会察觉到它们的存在。有了CVS,你可以很容易地恢复旧版本,并从中看出到底是哪个修改导致了这个bug 。有时这是很有用的。 

当然了,你可能把所有版本的所有文件都保存了下来。但这会浪费大量的磁盘空间。而CVS用一种聪明的办法来保存一个文件的所有版本——仅仅保存不同版本之间的区别——在一个文件里。 

如果你是项目开发组的一员,CVS也会帮助你。除非极为小心,成员之间很容易互相覆盖文件。一些编辑器,如GNU Emacs,会保证同一时间内同一文件绝不会被两个人修改。不幸的是,如果有人用了另外的编辑器,这种保护就没用了。CVS用隔离开不同的开发者解决了这个问题。每个开发者在他自己的目录里工作,等每一个开发者都完成了他们自己的工作后,CVS会将它们合并到一起。 

CVS最初由Dick Grune在1986年12月以shell scripts的形式发布在comp.sources.unix的新闻组第6卷里。虽然当前的CVS中没什么代码来自于这些shell scripts,但许多CVS的冲突解决算法是从它们来的。 

1989年4月,Brian Berliner设计了CVS并编写了代码,之后Jeff Polk帮助Brian设计了CVS模块发行分支。 

你可以从好多渠道得到CVS,包括从INTERNET上自由下载。有关下载CVS和其它与CVS相关的话题,请访问下面网址: 

http://www.cvshome.org/
http://www.loria.fr/~molli/cvs-index.html
 


有一个关于CVS的邮件列表,名叫info-cvs,要订阅或退订请发email: info-cvs-request@gnu.org。如果你更喜欢新闻组,comp.software.config-mgmt可能比较适合于讨论CVS(还有其它一些配置管理系统)。将来,可能会创立一个comp.software.config-mgmt.cvs, 当然那要确取决于在comp.software.config-mgmt上有足够的CVS讨论。 

你也能订阅bug-cvs邮件列表,详见[附录 H]。要订阅可以发emal到bug-cvs-request@gnu.org。 




CVS不是什么?
CVS可以为你做很多,但不要指望它能为每一个人做每一件事情。 


CVS不是一个BUILD系统。
虽然你的源码库(repository)和模块文件与你的BUILD系统互相作用(例如:Makefiles),但它们本质上还是互相独立的。 

CVS不能指导你如何构造什么,它只是将你所设计的文件以一种树结构保存下来以备恢复之用。 

CVS不能决定如何在一个检出的目录使用磁盘空间。如果你在每一个目录中都写下Makefiles或脚本,且必须知道其它一切的相对位置,有时不得不要检出整个源码库。 

如果你将你的工作模块化,并且建立了一个共享文件的build系统(通过links,mounts,Makefiles里的VPATH等),你就可以随意安排磁盘的使用。 

不过你要记住构建和维护这样一个系统是要做许多工作的,而CVS不善此道。 

当然了,你应该在CVS下放一个工具来支持这样一个构造系统(脚本,Makefiles,等等)。 

当有些变化发生在CVS范围之外时,要想想什么文件需要重建。一个传统的方法是用make来构造,并用一些自动化的工具来产生make所用的相关文件。 

关于结合CVS进行build,请参考[第 14 章]。 

CVS不能替代管理.
你的经理和项目负责人应经常与你交流以确保你时时记得进度表、合并点、分支名和发布日期。如果他们不这样做,CVS也没用。 

CVS只是一个用来使你的资源与你的步调一致的工具。但你是风笛手和作曲家。没有哪种乐器会自己演奏或是作曲。 

CVS 不能代替开发者之间的交流.
在单个文件内遇到冲突时,大多数开发者不费多大力气就能解决它们。但更常见的"冲突(conflict)",是那些难度较大、不在开发者之间进行交流就没法解决的问题。 

当在一个文件内或多个文件中同时发生变化时,CVS并不知道何时它们会在逻辑上发生冲突。它的冲突(conflict)概念是纯粹文本意义上的,这种冲突会在同一个文件的两种变化十分接近以致于会破坏合并命令(如diff3)。 

CVS决不会指出程序逻辑上非文本或分布式的冲突。 

例如:假如你在文件A中改变了函数X的参数。同时,别人在编辑文件B,仍用旧参数调用X这个函数。此时产生的冲突CVS可就无能为力了。 

要养成经常阅读说明书和经常与你的同伴交谈的习惯。 

CVS没有变化控制
变化控制可以指许多事情。首先它的意思可以是BUG跟踪(bug-tracking),就是说它能维持一个数据库,其中包括已报告的BUG和每一个BUG状态(比如:是否已更正?在哪一个版本中?提交这个BUG的人是否认为已经更正?)。为了使CVS和一个外部的跟踪BUG系统协调一致,请参考rcsinfo和verifymsg文档[附录 C]。 

变化控制的另一个方面指跟踪这样的情况,即对好几个文件的改变实际上只是同一个逻辑变动。如果你在一次cvs commit操作中改变了几个文件,CVS会忘掉它们是一起改变的,即便它们共用一个LOG信息。做一个GNU风格的Changelog可能会有点用。 

在一些系统中,变化控制的另一个方面是跟踪每一个变化的状态的能力。一些变化由一个开发者写出,而另一些变化则由另一个开发者来作出评论,等等。一般来讲,用CVS来做,是产生一个diff(用cvs diff或diff),可以用patch来利用。这个非常灵活,但依赖于CVS之外的机理以保证事情不会崩溃。 

CVS不是自动测试程序
测试套件可以利用commitinfo文件。不过我没有听说过多少项目试图那样做或whether there are subtle gotchas。 

CVS没有内建的处理模型
有些系统提供一些方法确保变更或发布通过不同的步骤,以及各种所需的批准过程。一般地,你可以用CVS来完成它,但是有点不太够。有些情况下你想用commitinfo, loginfo, rcsinfo或verifymsg文件,要求在CVS提交之前完成某些操作。你也会考虑诸如branches和tags等特性是否能用在一个开发树,然后合并仅被证明一次的修改到一个稳定的树。 



例子

作为一种介绍CVS的方式,我们将使用CVS进行一次演练(work-session)。第一个要明白的是CVS把所有的文件集中保存在一个源码库(repository)[第 2 章]中;在此我们假定已建立好一个源码库。 

假定你开发的是一个简单的编译器。源文件包括几个C文件和一个Makefile。编译器叫tc(Trivial Compiler), 同时源码库已建立。因此有一个叫tc的模块。 

获取源文件
首先要做的是得到一份tc源文件的工作拷贝。你需要用checkout命令: 

$ cvs checkout tc
 


这样会创建一个名为tc的新目录并把源文件复制到这个目录中。 

$ cd tc
$ ls
CVS         Makefile    backend.c   driver.c    frontend.c  parser.c
 


CVS目录是CVS内部使用的。正常情况下,不要改变或移动里面的任何文件。 

用你的编辑器,对backend.c进行修改,几小时的优化后通过了编译器。RCS和SCCS使用者应注意:不必锁住你想编辑的文件。详细解释请参考[第 10 章]。 

提交修改
当你刚用编译器检查过文件可以编译时,你却决定对backend.c做新的修改。CVS会把你的新文件保存在源码库中并且使用同一源码库的任何人也可以得到它。 

$ cvs commit backend.c
 


CVS打开一个编辑器,让你输入一个日志信息。你敲入“Added an optimization pass.”, 保存这个临时文件,退出了编辑器。 

环境变量$CVSEDITOR决定运行哪一个编辑器。如果没有设置$CVSEDITOR而设置了环境变量$EDITOR,那么就会启用后者。如果两者都未设置,那么会启用一个默认编辑器,比如在unix系统上会是vi, 在Windows NT/95系统是notepad。 

做为补充, cvs还会检测$VISUAL环境变量. 这取决于是否需要和以后的CVS版本是否检测$VISUAL. 不必多虑,你不设置$VISUAL或者将它与$EDITOR设成一样. 

当CVS启动编辑器时,它包含了一个被修改的文件的名单。对于CVS客户,这个名单基于文件的修改时间和它最近一次被修改的时间。因此,如果一个文件的修改时间改变了而内容没有,它就好象一个修改过的文件一样。处理这种情况最简单的的办法是别管它——如果你使用提交的话,CVS会检测到它的内容没有改变,从而把它作为未改变的文件来处理。下一次update会告知CVS此文件没有修改,并会重设时间标记以便此文件不会在以后的编辑过程中出现。 

如果你想避免打开一个编辑器,你可以在命令行使用-m标记来指定日志信息,如下所示: 

$ cvs commit -m "Added an optimization pass" backend.c
 


清除
在你转到其他程序任务之前,如果要删除tc的工作拷贝,一般采用如下方法: 

$ cd ..
$ rm -r tc
 


但是更好的方法是使用release命令[release--Indicate that a Module is no longer in use 在 附录 A]: 

$ cd ..
$ cvs release -d tc
M driver.c
? tc
You have [1] altered files in this repository.
Are you sure you want to release (and delete) directory `tc': n
** `release' aborted by user choice.
 


release命令检查你所做的所有更改。如果打开历史纪录功能,它会同时在历史档案文件中加入一条注释。[The history file 在 附录 C]。 

当你用release的-d参数时,它将删除你的工作拷贝。 

在以上的例子中,release命令向输出设备写了几行文字。? tc意思是CVS不认识文件tc。这一点你不需要担心。tc是一个可执行文件,它不会被存储在源码库中。关于如何消除这些警告,参见[Ignoring files via cvsignore 在 附录 C]。参见[release output 在 附录 A],可以得到release所有可能的输出。 

M driver.c更严重一些。这表明driver.c这个文件在检出后已经被更改过了。 

release命令通常在结尾处告诉你在工作目录有多少源件的拷贝已经被更改了,然后在删除或在历史档案中进行更改之前向你确认。 

你认为安全的情况下,按n RET就可以了。 

查看差异
你忘记了driver.c是否被更改,想查询一下这个文件的更改情况。 

$ cd tc
$ cvs diff driver.c
 


这个命令diff可以检查driver.c的检出版本和工作目录中版本的差异。看到输出后要你记起增加了一个命令行选项使优化可以执行。提交之后,release这个模块。 

$ cvs commit -m "Added an optimization pass" driver.c
Checking in driver.c;
/usr/local/cvsroot/tc/driver.c,v  <--  driver.c
new revision: 1.2; previous revision: 1.1
done
$ cd ..
$ cvs release -d tc
? tc
You have [0] altered files in this repository.
Are you sure you want to release (and delete) directory `tc': y
  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值