1、简介<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

  CVS Concurrent Version System(并行版本系统)的缩写,用于版本管理.如果大家曾经参与过多人协作开发的项目,大家肯定有这样的痛苦经历:由于多个人同时修改同一个文件, 自己辛辛苦苦修改的程序被别人彻底删除了.另外,如果你的软件/程序已经发布了三个版本, 而这时候用户需要你修改第二个版本的东西,也许你会因为只保留了最新版本而痛哭流涕。还有就是你对程序做了一些修改,但是修改很少,你只想给远方的同事发一个两个版本之间的差别文件,这样可以免于邮箱不够大,网速太慢之类的问题.为了解决类似这样的问题,以及诸如生成补丁文件,历史版本修改等,一帮***(褒义)在原先 Unix 体系里很成熟的 SCCS RCS 的基础上,开发了 CVS(SCCSSource Code Control SystemRCSRevision Control System)
  CVS 的基本工作思路是这样的:在一台服务器上建立一个仓库,仓库里可以存放许多不同项目的源程序。由仓库管理员统一管理这些源程序.这样,就好象只有一个人在修改文件一样.避免了冲突.每个用户在使用仓库之前,首先要把仓库里的项目文件下载到本地。用户做的任何修改首先都是在本地进行,然后用 cvs 命令进行提交,由 cvs 仓库管理员统一 修改.这样就可以做到跟踪文件变化,冲突控制等等.
由于 CVS 是典型的 C/S 结构的软件,因此它也分成服务器端和客户端两部分。不过大多数CVS 软件都把它们合二为一了。我们这里就分别从服务器和客户端的角度讨论cvs的使用。

 

2、第一次工作

cvs数据库提出项目代码,例如,提出项目8501的源文件,执行如下命令:
$cvs checkout  8501
在用户的主目录中会自动创建一个8501目录,8501的所有源文件即被提出到了其中。

3、第二次工作

记住,从此以后,需要提取项目源文件就不需要再重新checkout了,只需要进入项目的目录,更新一下就行了:例如需要再次提出8501的所有源代码,进入到用户自己的主目录下的8501目录中,
$cd
 8501 
执行命令
$cvs
  update
一下即可.又或者不想直接更新,只是想看看有没有更新的东西,那么: 

$cvs
 
status
这时后会打印出一长串状态报告(你可能需要用类似less这样的命令分页显示,或者定向到一个输出文件里慢慢看.),对项目中的每个文件有一份状态报告,类似这样: 

===================================================================
 

File:
 foo.c             Status: Up-to-date 

   Working revision: <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />   1.1.1.1 'Some Date' 

   Repository revision: 1.2     /home/cvsroot/cvstest/foo.c,v 

   Sticky Tag:          (none) 

   Sticky Date:         (none) 

   Sticky Options:      (none) 


这里最重要的就是 Status 栏,这里总共可能有四种状态: 

Up-to-date
:表明你要到的文件是最新的. 

Locally
 Modified:表明你曾经修改过该文件,但还没有提交,你的版本比仓库里的新. 

Needing
 Patch:表明有人已经修改过该文件并且已经提交了!你的版本比仓库里的旧. 

Needs
 Merge:表明你曾经修改过该文件,但是另外也有人也修改了这个文件,而且还提交给仓库了! 


4、提交你的工作
你对某个文件做了修改,比如说改了ceo.c,加了一行程序:printf("where can I find 
VC to cheat!"); 
改完之后你要把修改提交给仓库,用命令: 

$cvs
 commit -m "add a complain" ceo.c 

或者就是: 

$cvs
 commit -m "worry about money" 

cvs帮你检查哪个文件需要提交. 

 

 

5、增加文件或者目录

假如要增加一个文件,例如: garbage_china_concept_stocks_list: 
执行命令
$cvs
 add garbage_china_concept_stocks_list 

然后还要: 


$cvs
 commit  garbage_china_concert_stocks_list 


看起来有点象数据库里的事务?的确是这样.CVS维护着一个本地的参考文件(在CVS/Entries里),这样提交的时候就可以一次地把所有改变放到服务器端,这样也更安全。

 

6、删除文件或者目录

 假如想删除一个文件,例如:bankrupted_web_site: 
执行命令

$rm
 bankrupted_web_site 
$cvs
 remove bankrupted_web_site 

$cvs
 commit bankrupted_web_site 



7、解决协同项目工作中的冲突

如果只是想保持软件的同步的话,那么上面的命令就足够用了.可是如果多人协作开发项目的话,可就不是了这么简单了.当你参加项目,维护文件时,就需要更多命令,比如说你我都是8501项目的开发人员: 

1
,你对某个文件做了修改,比如说改了ceo.c,加了一行程序:printf("where can I find        VC to cheat!"); 

改完之后你要把修改提交给仓库,用命令: 

$cvs
 commit -m "add a complain" ceo.c 

或者就是: 

$cvs
 commit -m "worry about money" 

cvs帮你检查哪个文件需要提交. 


2
,当我每次开始工作的时候,会先执行一下

$cvs
 status 
这时候我会看到: 


==================================================================
 

File:
 ceo.c             Status: Needing Patch 


   Working revision:    1.1.1.1 'Some Date' 

   Repository revision: 1.2     /home/cvsroot/nastaq/ceo.c,v 

   Sticky Tag:          (none) 

   Sticky Date:         (none) 

   Sticky Options:      (none) 


于是我知道你改了ceo.c,于是就: 

$cvs
 update ceo.c 

或者干脆: 

$cvs
 update 

ceo.c这个文件更新为最新版本,然后再工作.然后提交給cvs数据库. 


如果这天有人修改了coo.c,加了一行 puts("how about another kind of bragging?"); 

并且提交了,但是这时候你已经 $cvs status 过了,就是说你不知道其他人的修改. 

而你加了一行printf("You must shamelessly and seems knowingness to act as a coo");并且提交了: 

$cvs
 commit coo.c 

这时候,CVS会告诉你 

cvs
 commit: Examing . 

cvs
 server: Up-to-date check failed for 'coo.c' 

cvs
 [server aborted]: correct above error first! 


于是你可以知道有人在你修改文件的当口做了提交,于是你可以执行 

$cvs
 update 

这时cvs会报告: 

RCS
 file: /home/cvsroot/nasdaq/coo.c,v 

retrieving
 revision 1.1.1.1 

retrieving
 revision 1.2 

Merging
 differences between 1.1.1.1 and 1.2 into coo.c 

rcsmerge:
 warning: conflicts during merge 

cvs
 update: conflicts found in coo.c 

C
 coo.c 

告诉你coo.c有版本冲突,于是你可以编辑coo.c,这时一般文件里看起来象这样: 

  ... 

printf("You
 must shamelessly and seems knowingness to act as a coo"); 

<<<<<<<
 foo.c 

=======
 

...
 

  puts("how about another kind of bragging?"); 

>>>>>>>
 1.2 

...
 


于是你把上面改成: 

printf("You
 must shamelessly and seems knowingness to act as a coo"); 

puts("how
 about another kind of bragging?"); 

然后 

$cvs
 commit -m "merged" coo.c 

于是下回你再更新的时候就有新的补钉要打...如此往复,直到完成所有修改. 

不过这里有一些要注意的地方就是删除程序,如果你删掉一行对你可能没有用的程序 

puts("to
 be honest"); 而我不想删除(因为我有用),而我不知情地直接: 

$cvs
 update 

了,那么我的这行程序也完蛋了,所以这里我们要注意所有开发人员的协调,千万不要 

乱删东西,大不了用 

#if
    0 

#endif
 

宏定义对括起来.实在要删东西,那最好先标记一个版本: 

$cvs
 tag v_0_0_1 


8、发布版本


然后你可以发布并删除你自己的工作目录里这个版本的文件(注意:不是删除仓库里的.): 

$cvs
 release -d nasdaq 


9、形成分支
然后你再生成一个新分支: 

$cvs
 rtag -b -r v_0_0_1 v_0_0_1_1 nasdaq 


然后再建立v_0_0_1_1的分支 


$cvs
 checkout -r v_0_0_1_1 nasdaq 


编辑并修改这个分支的文件,这样的做法比较好.