开源中文网

您的位置: 首页 > Linux应用 > CVS > 正文

CVS使用手册

来源:  作者:

结合文档和一些网上资源,折腾了半天终于搞定了CVS,我写一点非常简单的"速成" 
的教材.希望对大家有用.  

下面是我的步骤和做法.  

1,要求:  

root 权限;  
CVS软件,请找到相关的rpm,tgz,deb 等包装上,或者到  

http://www.cvshome.org/CVS/Dev/code  
下载原程序编译安装,这里我不准备介绍它的安装,请参考CVS自身的文档安装. 
我使用Slackware的tgz包,安装的命令是  
#installpkg cvs*.tgz  
其他包请参考对应包管理工具的命令.  
一定的系统资源,要有一定内存(32M就能工作得很好),要一定的磁盘空间,看 
你的项目的大小和多少而定.  
2,架设CVS服务器:  
建立CVSROOT目录,因为这里涉及到用户对CVSROOT里的文件读写的权限问题, 
所以比较简单的方法是建立一个组,然后再建立一个属于该组的帐户,而且以后有 
读写权限的用户都要属于该组.假设我们建一个组cvs,用户名cvsroot.建组和用 
户的命令如下  
#groupadd cvs  
#adduser cvsroot 
生成的用户家目录在/home/cvsroot(根据自己的系统调整)  
用cvsroot用户登陆,修改 /home/cvsroot (CVSROOT)的权限,赋与同组人有读写 
的权限:  
$chmod 771 . (或者770应该也可以)  
注意:这一部分工作是按照文档说明做的,是否一定需要这样没有试验,我 
会在做试验后在以后版本的教程说得仔细一点.如果您有这方面的经验请提 
供给我,谢谢.  
  

建立CVS仓库,(仍然是cvsroot用户),用下面命令:  
$cvs    -d /home/cvsroot init 
以root身份登陆,修改/etc/inetd.conf 和 /etc/services,分别加入下面一行:  
在 /etc/inetd.conf 里加入:  
cvsserver    stream    tcp    nowait    root    /usr/bin/cvs    cvs --allow-root=/home/cvsroot pserver  
说明:上面的行是单独一整行,/usr/bin/cvs 应该是你的cvs版本的命令路径, 
请根据自己的系统调整./home/cvsroot 是你建立的CVSROOT的路径,也请 
根据上面建立目录的部分的内容做调整.  

在/etc/services里加入:  
cvsserver    2401/tcp  

说明:cvsserver是任意的名称,但是不能和已有的服务重名,也要和上面修 
改/etc/inetd.conf那行的第一项一致.这里我用的是CVS的口令认证方式, 
CVS还有其他认证方式,我没有做试验,如果您有经验,请补充,谢谢.  
  

添加可以使用CVS服务的用户到cvs组:  
以root身份修改/etc/group,把需要使用CVS的用户名加到cvs组里,比如我想 
让用户laser和gumpwu能够使用CVS服务,那么修改以后的/etc/group应该有下 
面这样一行:  
cvs:x:105:laser,gumpwu  
在你的系统上GID可能不是105,没有关系.主要是要把laser和gumpwu用逗号 
分隔开写在最后一个冒号后面.当然,象RedHat等分发版有类似linuxconf这样 
的工具的话,用工具做这件事会更简单些. 
重起inetd使修改生效:  
#killall -HUP inetd 
这样服务器就设置完成了.我们接着搞客户端.  
3,设置客户端,如果是Linux(或者其他*nix),客户端和服务器端的软件是一样的,如果是 
Win,MAC等平台,请到http://www.loria.fr/cgi-bin/molli/wilma.cgi/rel 找相应的客户端软件, 
这里我先说一下在Linux(*nix)里怎么做:  

设置环境变量CVSROOT:  
$export CVSROOT=:pserver:laser@the_server_name:/home/cvsroot  
注意:这里的pserver是访问方式,我在上面设置的是口令认证,所以这里是 
pserver,如果你的CVS服务器设置成别的访问模式,那么需要相应修改. 
laser是可以使用 CVS服务器的用户名,这里可以根据你的设置修改,我在这 
个版本设置的是直接使用系统用户的口令文件,也就是说laser必须是CVS服 
务器上的合法用户,这里当然有安全问题,CVS可以设置成为拥有自己的用户, 
我将在以后的版本里面增加这些内容,或者您也可以提供一些补充,或者直接 
读CVS的文档.the_server_name是CVS服务器的名称或者IP地址,根据你的情 
况填写,/home/cvsroot是你的CVS服务器的CVSROOT目录,根据你的CVS服务 
器设置做修改或者询问管理员.你可以把这行放到你的shell的profile里 
(.bash_profile,.profile等)这样就不用每次敲一长串命令了.  
  

登陆CVS服务器:  
$cvs login,这时候cvs会问你口令,请把你在CVS服务器上的口令敲进去,这里 
是laser在CVS服务器上的系统用户的口令:  
 Passwd:xxxxxxxx  
成功登陆后将在你的家目录建立一个.cvspass文件,以后就不用输入口令了. 
好,客户端设置完成,简单吧.  
现在服务器和客户端都设置好了,那么怎么用呢,我在这里写一个最简单的(估计也是最常用 
的)命令介绍:  
首先,建立一个新的CVS项目,一般我们都已经有一些项目文件了,这样我们可以用下面步骤 
生成一个新的CVS项目:  

进入到你的已有项目的目录,比如叫cvstest:  
$cd  cvstest 
运行命令:  
$cvs import -m "this is a cvstest project" cvstest     v_0_0_1     start  
说明:import 是cvs的命令之一,表示向cvs仓库输入项目文件.  
              -m参数后面的字串是描述文本,随便写些有意义的东西,如果不加 -m 参 
数,那么cvs会自动运行一个编辑器(一般是vi,但是可以通过修改环境变量 
EDITOR来改成你喜欢用的编辑器.)让你输入信息,  
             cvstest 是项目名称(实际上是仓库名,在CVS服务器上会存储在以这个名字 
命名的仓库里.)  
             v_0_0_1是这个分支的总标记.没啥用(或曰不常用.)  
             start 是每次 import 标识文件的输入层次的标记,没啥用. 
这样我们就建立了一个CVS仓库了,然后,我们可以把这个测试项目的文件删除.试验一下如何 
从仓库获取文件.这里我假设上面的所有客户端工作你都已经做过了.  
运行下面的命令:  
   $cvs checkout cvstest 
从仓库中检索出cvstest项目的源文件.  
如果你已经做过一次checkout了,那么不需要重新checkout,只需要进入cvstest项目的目录,更新 
一把就行了:  
$cd cvstest  
$cvs update 
一下即可.又或者你不想直接更新,只是想看看有没有更新的东西,那么:  
$cvs status 
这时后会打印出一长串状态报告(你可能需要用类似less这样的命令分页显示,或者定向到一个输 
出文件里慢慢看.),对项目中的每个文件有一份状态报告,类似这样:  
===================================================================  
File: foo.c             Status: Up-to-date  
   Working revision:    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:表明你曾经修改国该文件,但是偏偏有个不识相的也修改了这个文件,而且还提交 
给仓库了!  

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

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这个文件更新为最新版本,然后再干活.然后提交.  

如果这天你修改了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  

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

$cvs release -d nasdaq  

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

$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  

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

还有一些命令,比如要增加一个文件 garbage_china_concept_stocks_list:  

$cvs add garbage_china_concept_stocks_list  

然后还要:  

$cvs commit  garbage_china_concert_stocks_list  

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

$rm bankrupted_web_site  
$cvs remove bankrupted_web_site  
$cvs commit bankrupted_web_site  
   

好了,上面所有的东西,估计就是我们用cvs时80%情况下用的命令和内容,包括文件的更新,提 
交,冲突的解决,分支的派生,增删文件等.实际上cvs的功能之强大,远远超出我在这里描述的 
内容,我这个"速成"也就管不了太多了,希望随着时间的推移,我们能够更加有效地使用CVS. 
也希望大家能够不断补充这篇文章,最后能够成为手册,而不仅仅是速成.当然,还要更多地参考 
别的文档.  

创建于: 2008-02-14 17:31:50,修改于: 2008-02-14 17:31:50,已浏览21次,有评论1条 
网友评论 
网友:flyrambler 时间:2008-02-14 17:35:11 IP地址:202.96.60.★ 


CVS常用命令速查手册 
CVS是一个C/S系统,多个开发人员通过一个中心版本控制系统来记录文件版本,从而达到保证文件同步的目的。工作模式如下: 
   
  CVS服务器(文件版本库) / | \ (版 本 同 步) / | \开发者1 开发者2 开发者3 
  开发人员入门可以主要挑选2,6看就可以了,CVS的管理员则更需要懂的更多一些,最后还简单介绍了一些Windows下的cvs客户端使用,远程用户认证的选择,及与BUG跟踪系统等开发环境的集成问题。 
   
  CVS环境初始化:CVS环境的搭建 管理员 
  CVS的日常使用:日常开发中最常用的CVS命令, 开发人员 管理员 
  CVS的分支开发:项目按照不同进度和目标并发进行 管理员 
  CVS的用户认证:通过SSH的远程用户认证,安全,简单 管理员 
  CVSWEB:CVS的WEB访问界面大大提高代码版本比较的效率 管理员 
  CVS TAG:将$Header$加入代码注释中,方便开发过程的跟踪 开发人员 
  CVS vs VSS: CVS和Virsual SourceSafe的比较 开发人员 管理员 
  WinCVS: 通过SSH认证的WinCVS认证设置 
  基于CVSTrac的小组开发环境搭建:通过CVSTrac实现web界面的CVS用户管理及集成的BUG跟踪和WIKI交流。 
  一个系统20%的功能往往能够满足80%的需求,CVS也不例外,以下是CVS最常用的功能,可能还不到它全部命令选项的20%,更多的功能在实际应用过程中体会,你想用多少就学多少,不时回头看看经常有意外的收获。 
   
  CVS环境初始化 
  ============ 
   
  环境设置:指定CVS库的路径CVSROOT 
  tcsh 
  setenv CVSROOT /path/to/cvsroot 
  bash 
  CVSROOT=/path/to/cvsroot ; export CVSROOT 
   
  后面还提到远程CVS服务器的设置: 
  CVSROOT=:ext:$USER@test.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH 
   
  初始化:CVS版本库的初始化。 
  cvs init 
   
  一个项目的首次导入 
  cvs import -m "write some comments here" project_name vendor_tag release_tag 
  执行后:会将所有源文件及目录导入到/path/to/cvsroot/project_name目录下 
  vender_tag: 开发商标记 
  release_tag: 版本发布标记 
   
  项目导出:将代码从CVS库里导出 
  cvs checkout project_name 
  cvs 将创建project_name目录,并将最新版本的源代码导出到相应目录中。这个checkout和Virvual SourceSafe中的check out不是一个概念,相对于Virvual SourceSafe的check out是cvs update, check in是cvs commit。 
   
  CVS的日常使用 
  ============= 
   
  注意:第一次导出以后,就不是通过cvs checkout来同步文件了,而是要进入刚才cvs checkout project_name导出的project_name目录下进行具体文件的版本同步(添加,修改,删除)操作。 
   
  将文件同步到最新的版本 
  cvs update 
  不制定文件名,cvs将同步所有子目录下的文件,也可以制定某个文件名/目录进行同步 
  cvs update file_name 
  最好每天开始工作前或将自己的工作导入到CVS库里前都要做一次,并养成“先同步 后修改”的习惯,和Virvual SourceSafe不同,CVS里没有文件锁定的概念,所有的冲突是在commit之前解决,如果你修改过程中,有其他人修改并commit到了CVS库中,CVS会通知你文件冲突,并自动将冲突部分用 
  >>>>>> 
  content on cvs server 
  <<<<<< 
  content in your file 
  >>>>>> 
  标记出来,由你确认冲突内容的取舍。 
  版本冲突一般是在多个人修改一个文件造成的,但这种项目管理上的问题不应该指望由CVS来解决。 
   
  确认修改写入到CVS库里 
  cvs commit -m "write some comments here" file_name 
   
  注意:CVS的很多动作都是通过cvs commit进行最后确认并修改的,最好每次只修改一个文件。在确认的前,还需要用户填写修改注释,以帮助其他开发人员了解修改的原因。如果不用写-m "comments"而直接确认`cvs commit file_name` 的话,cvs会自动调用系统缺省的文字编辑器(一般是vi)要求你写入注释。 
  注释的质量很重要:所以不仅必须要写,而且必须写一些比较有意义的内容:以方便其他开发人员能够很好的理解 
  不好的注释,很难让其他的开发人员快速的理解:比如: -m "bug fixed" 甚至 -m "" 
  好的注释,甚至可以用中文: -m "在用户注册过程中加入了Email地址校验" 
   
  修改某个版本注释:每次只确认一个文件到CVS库里是一个很好的习惯,但难免有时候忘了指定文件名,把多个文件以同样注释commit到CVS库里了,以下命令可以允许你修改某个文件某个版本的注释: 
  cvs admin -m 1.3:"write some comments here" file_name 
   
  添加文件 
  创建好新文件后,比如:touch new_file 
  cvs add new_file 
  注意:对于图片,Word文档等非纯文本的项目,需要使用cvs add -kb选项按2进制文件方式导入(k表示扩展选项,b表示binary),否则有可能出现文件被破坏的情况 
  比如: 
  cvs add -kb new_file.gif 
  cvs add -kb readme.doc 
   
  然后确认修改并注释 
  cvs ci -m "write some comments here" 
   
  删除文件 
  将某个源文件物理删除后,比如:rm file_name 
  cvs rm file_name 
  然后确认修改并注释 
  cvs ci -m "write some comments here" 
  以上面前2步合并的方法为: 
  cvs rm -f file_name 
  cvs ci -m "why delete file" 
  注意:很多cvs命令都有缩写形式:commit=>ci; update=>up; checkout=>co/get; remove=>rm; 
   
  添加目录 
  cvs add dir_name 
   
  查看修改历史 
  cvs log file_name 
  cvs history file_name 
   
  查看当前文件不同版本的区别 
  cvs diff -r1.3 -r1.5 file_name 
  查看当前文件(可能已经修改了)和库中相应文件的区别 
cvs diff file_name 
  cvs的web界面提供了更方便的定位文件修改和比较版本区别的方法,具体安装设置请看后面的cvsweb使用 
   
  正确的通过CVS恢复旧版本的方法: 
  如果用cvs update -r1.2 file.name 
  这个命令是给file.name加一个STICK TAG: "1.2" ,虽然你的本意只是想将它恢复到1.2版本 
  正确的恢复版本的方法是:cvs update -p -r1.2 file_name >file_name 
  如果不小心已经加成STICK TAG的话:用cvs update -A 解决 
   
  移动文件/文件重命名 
  cvs里没有cvs move或cvs rename,因为这两个操作是可以由先cvs remove old_file_name,然后cvs add new_file_name实现的。 
   
  删除/移动目录 
  最方便的方法是让管理员直接移动,删除CVSROOT里相应目录(因为CVS一个项目下的子目录都是独立的,移动到$CVSROOT目录下都可以作为新的独立项目:好比一颗树,其实砍下任意一枝都能独立存活),对目录进行了修改后,要求其开发人员重新导出项目cvs checkout project_name 或者用cvs update -dP同步。 
   
  项目发布导出不带CVS目录的源文件 
  做开发的时候你可能注意到了,每个开发目录下,CVS都创建了一个CVS/目录。里面有文件用于记录当前目录和CVS库之间的对应信息。但项目发布的时候你一般不希望把文件目录还带着含有CVS信息的CVS目录吧,这个一次性的导出过程使用cvs export命令,不过export只能针对一个TAG或者日期导出,比如: 
  cvs export -r release1 project_name 
  cvs export -D 20021023 project_name 
  cvs export -D now project_name 
   
  CVS Branch:项目多分支同步开发 
  ============================= 
   
  确认版本里程碑:多个文件各自版本号不一样,项目到一定阶段,可以给所有文件统一指定一个阶段里程碑版本号,方便以后按照这个阶段里程碑版本号导出项目,同时也是项目的多个分支开发的基础。 
  cvs tag release_1_0 
   
  开始一个新的里程碑: 
  cvs commit -r 2 标记所有文件开始进入2.x的开发 
   
  注意:CVS里的revsion和软件包的发布版本可以没有直接的关系。但所有文件使用和发布版本一致的版本号比较有助于维护。 
   
  版本分支的建立 
  在开发项目的2.x版本的时候发现1.x有问题,但2.x又不敢用,则从先前标记的里程碑:release_1_0导出一个分支release_1_0_patch 
  cvs rtag -b -r release_1_0 release_1_0_patch proj_dir 
   
  一些人先在另外一个目录下导出release_1_0_patch这个分支:解决1.0中的紧急问题, 
  cvs checkout -r release_1_0_patch 
  而其他人员仍旧在项目的主干分支2.x上开发 
   
  在release_1_0_patch上修正错误后,标记一个1.0的错误修正版本号 
  cvs tag release_1_0_patch_1 
   
  如果2.0认为这些错误修改在2.0里也需要,也可以在2.0的开发目录下合并release_1_0_patch_1中的修改到当前代码中: 
  cvs update -j release_1_0_patch_1 
   
  CVS的远程认证:通过SSH远程访问CVS 
  ================================ 
   
  使用cvs本身基于pserver的远程认证很麻烦,需要定义服务器和用户组,用户名,设置密码等, 
  常见的登陆格式如下: 
  cvs -d :pserver:cvs_user_name@cvs.server.address:/path/to/cvsroot log

Tags:CVS手册
相关文章列表:
关于开源中文网 - 联系我们 - 广告服务 - 网站地图 - 版权声明