学习 CVS 版本控制系统

学习 CVS 版本控制系统

从来没有试过版本控制系统,所以想学学。看介绍,微软的VSS似乎不错,不过一下子没找到,后来在网上找到了windows 平台上可以安装的CVS NT和WINCVS这两个软件,其中WinCVS还号称中文版。

安装挺顺利,都装好了。然后看它们带的说明书,CVSNT是服务器端软件,自带了一个帮助文件,当然是英文的。看了半天,举的例子都是LINUX上的,开头讲了半天CVS不是什么不是什么的东东,就是没讲如何一步步架设一个可用的CVS服务器,对我这种对CVS还没有任何感慨认识的人来说,它讲的东西都是一头雾水。而且我又不懂英语:(

WINCVS是客户端,它没讲服务器端该如何架设。虽然它的说明书是中文的,但在另一半还没有架好的情况下,对我来说还是很难用起来的。

看来这些写说明书的人都是一帮很傻的人,他们以为一些概念很初级,就忽略了。其实我们认识一样东西,学一样东西,都是从感性到理性一步步深入的。一开头解释很多术语,只会让人更加迷惑。

2005-7-17 10:17:22   

查看评语»»»    

 2005-7-17 10:26:49    [转]用CVSNT与WINCVS实现CVS的架设

本文是写给希望能够马上通过CVS来进行更好的开发管理的小型团队或个人。相信CVS的绝妙之处大家已经从网上的文章中有了一个大概的了解。它的优点我就不在这里进行介绍了。

  我在这里只想说一句:你一但使用了CVS你就会发现你已经离不开它了。

  其实网上介绍CVS的相关文章也不少,而据我观察多数是英文的,多数没有任何图片,而且多数是介绍如何在unix操作系统下安装和配置CVS服务器。这显然不适和一些想尝试改进的小型团队,尤其是学生中间的业余团队。其中一个主要原因是这些团队主要采用的开发环境是微软的windows2000操作系统,如果专门提供一台安装unix操作系统的计算机来作为CVS服务器显然是不现实的。这会给本来好奇的人们产生对CVS的恐惧心理,觉得使用它是那么的困难和繁琐。所以,我构思写这篇文章——介绍如何在windows操作系统下安装和配置CVS服务器,并且加入了尽量多的图片——主要目的是让更多的人敢于尝试,并且能够领略到CVS那激动人心的强大功能。

  好下面让我们话入正题,以下是本文要介绍的主要内容:

  1、服务器端CVSNT的安装;

  2、CVS代码仓库的创建;

  3、配置CVS帐号;

  4、客户端WINCVS的安装与配置;

  5、使用WINCVS进行简单操作(包括commit、checkout等)。

  一、安装CVSNT

  我们知道,CVS是使用“客户端/服务器”(Client/Server)模式来工作的,这也是优秀版本控制系统的发展趋势。那么我们首先要有一台CVS服务器(当然这台电脑也可以同时作为客户端来使用)。本节所要介绍的就是如何利用CVSNT架设一台windows操作系统环境下的CVS服务器。CVSNT顾名思义,肯定是用在windows上的,此软件可以从  www.CVSNT.org   免费下载最新版本。

  先将它下载下来,然后双击开始安装:

会出现上面的对话框,这是无关紧要的,所以一路next按下去,直到出现下面的对话框

  这里需要选择“Full installation”,然后点击next,后面会出现以下对话框

  注意这里是需要将两个复选框都选中的。然后就可以高枕无忧,一路安装下来了。

  安装完成了,本节也就结束了,怎么样?还是挺简单的吧。

二、创建CVS代码仓库(Repository)

  在此我就不对CVS仓库的概念和用途做更多解释了,大家可以参考放飞网文档中心中的其他文章中的介绍。大家只要记住,CVS仓库是代码的每个版本和所有相关记录在服务器端的储存地。有些时候又称它为主拷贝(Master Copy),为什么呢,我们将在后面的章节中了解到。

  在创建CVS仓库之前,我们首先需要新建一个文件夹用于充当仓库。该文件夹最好不要与程序放在一起,以免万一系统崩溃时破坏数据。然后,点击“开始”->“程序”->“CVS for NT”->“configure server”,出现对话框后选择“Repositories”选项卡,就会出现如下对话框

点击下方的“add”按钮,会出现让你选择文件夹的对话框,选择我们刚才创建的文件夹,并确定,这时会发现上面所示对话框中央的列表框中发生了改变如下所示

  显示出了我们上面所创建的文件夹的路径。这样一个CVS仓库就创建好了。

  三、配置CVS帐号

  上面我们已经安装了CVSNT,并创建了一个CVS仓库。这时,我们需要给连接到服务器上的每一个客户端创建帐号,以保证他们可以正常地工作。

  最简单的办法是右键单击“我的电脑”,选择“管理”,在“本地用户和组”中右键单击“用户”,选择“新用户”进行帐户的添加。这样是创建了windows的用户,同时也就创建了CVS的帐户。

  四、WINCVS的安装与配置

  上面三节我们已经介绍了服务器端的全部步骤,现在我们已经有一台CVS服务器了,那么为了实现“客户端/服务器”(Client/Server)模式,我们现在还要继续创造一个或多个客户端。

  客户端使用的软件是WINCVS可以在  www.WINCVS.org   免费下载,它是图形界面的,比较直观,而且功能强大。WINCVS的安装没有什么特别的,和其他软件一样,双击就可以安装了。

  安装完成后,最重要的是对客户端进行配置,目的在于让CVS客户端根据配置信息找到服务器上需要访问的仓库。在WINCVS窗口菜单栏中选择“Admin”->“Preferences”出现如下对话框:

  在“CVSROOT”栏中输入配置字符串,格式如下:

:pserver:username@hostname(或IP地址):CVS仓库路径

  这个格式是绝对不能错的,否则CVS命令就不能正常执行。

  下面我解释一下上面的字符串的含义:

  1、“pserver” 是最常用的一直CVS远程访问方式;

  2、“username” 是指客户端在服务器上的用户名,也就是我们在上面的“配置CVS帐号”一结中讲到的;

  3、“hostname” 是CVS服务器的主机名,也可以是它的IP地址;

  4、“CVS仓库路径” 是一个CVS仓库所在的目录,用于区分你要访问的是哪个仓库(因为一个CVS服务器上可能有多个不同仓库)。

  例如::pserver:njx@frontfree-njx:/master

  配置完毕点击确定即可。到现在为止我们已经将CVS的“客户端/服务器”(Client/Server)模式实现了。为了确定一下上面的步骤都对了,我们要进行检验。最好的检验方法是让CVS客户端登录到服务器。在菜单栏里选择“Admin”->“Login”,会出现如下对话框:

  提示你输入密码。密码就是上面创建的帐号的密码。完成后点击ok,然后注意WINCVS窗口下方的命令结果输出窗口,如果出现下面的信息:

***** CVS exited normally with code 0 *****

  说明登录成功了,如果不是,就说明在做上面的步骤时出现了错误,请仔细检查。如果测试成功我们就开始可以使用CVS的强大功能了。

  注意:

  1、以上步骤同样适用于已经是CVS服务器的那台机器,也就是前面提到的又做服务器又做客户端。

  2、CVS的登录只需要一次成功登录就可以了,不必每次都登录。

五、WINCVS的简单操作

  不知不觉已经拥有了CVS服务器的你是否很兴奋呢?下面我们就要开始使用CVS了,本文只介绍CVS的简单操作,如果希望深入了解请参考放飞网文档中心的其他文章。

  也许你在兴奋之余会问,第一步应该干什么呢?

  首先,我们要在客户端创建一个文件夹,用于存放工作拷贝(关于工作拷贝的概念请参见放飞文档中心的其他相关文档中的相关介绍),工作拷贝是和上面提到的主拷贝相对应的,主拷贝只有一份,放在CVS仓库里,而工作拷贝却可以有很多份,分别放在不同的客户端。创建完文件夹后,我们将它的路径添加到WINCVS窗口上方的输入框中即可,从现在开始我们所有的工作拷贝都会存放在这个文件夹中,而我们对文件所做的修改也是针对这个文件夹中的文件。

  那么让我们开始一个新的项目,首先在一开始,我们要进行“checkout”过程,这个过程是将主拷贝中的目录及文件拷贝到你指定的客户端目录中。

  右键单击WINCVS窗口中左边的框,在弹出菜单中选择“checkout module”然后会出现如下对话框:

  在第一个输入框中只输入一个“.”,表示仓库中的全要复制一份作为工作拷贝。在第二个输入框中输入你存放工作拷贝的路径,然后点击“确定”即可。(如果今后主拷贝中有了目录的变化,客户端也要进行“checkout”过程才能看到)

  完成这一步之后才能进行其他操作,下面我们来模拟建立一个新的项目,并提交到CVS仓库中。首先,在你的工作目录下新建一个文件夹。再看一下WINCVS,会看到你刚创建的文件夹前面的图标是红色的,这是提示你选中它然后点击WINCVS按钮栏中的那个带加号的按钮,这是在CVS服务器上创建一个这样的目录。同样的如果你新建的是一个文件也是要这样添加。注意目录和文件要分别添加,别以为添加了目录,里面的文件也会被添加。在添加过程中会遇到这样一个对话框:

  这是CVS在提醒你输入记录信息,这会被记录在相应的日志中,便于今后查看。一定要认真填写,因为如果几天后你忘了你这天对文件做了什么,这就是最好的资料。如:Create a new project。之后点击确定就可以了。

  目录的添加到这步就结束了,而文件的添加还需要另外一步,就是文件的“commit”过程,这也适用于文件被修改后,向仓库提交。只要将需要提交的文件选中,然后右键单击,在弹出菜单里选择“commit selection”然后同样输入记录信息,点击确定。

  这时,另外一台客户端机器想看见项目的文件,可以在想获得最新版本的目录上单击右键选择“update selection”,之后就会发现其中的文件变成了最新版本,别人的改动也就一目了然了。

  以上我向大家介绍了在windows环境下架设CVS的方法并粗浅的介绍了WINCVS的基本功能,希望每个曾经因为没有条件而放弃CVS的开发团队或个人,都能用上自己的CVS。到此,本文也就结束了。

 

 2005-7-18 23:08:13    关于CVSNT 2.5.01(Travis) Build 1976 与 WinCVS 1.3中文版搭配遇到的几个问题。

安装了上述版本,照着WinCVS提供的相关中文文档,慢慢摸索。初步遇到几个问题:

1、CVSNT的用户账号好像需要是WINDOWS的系统账号,我装的是XP,在XP中建立的账号会显示在登录窗口中,很郁闷。

2、登录本机CVSNT服务成功,导入项目/模块成功,检出项目/模块也成功。但在修改一个文件后提交时,CVSNT返回出错信息,好像是在windows/temp目录下找不到临时文件。于是停止CVSNT服务,另外给它指定了一个临时文件目录,再启动服务。问题解决。

3、在递交强制版本时,CVS返回错误信息,如下:

cvs commit -m 测试提交新添加的文件 -r 2.0 "新建 文本文档.txt" (in directory D:/working/vch2/新建文件夹/)

Usage: cvs server [DnRlf] [-B bug | -b bug ] [-m msg | -F logfile] files...

 -b bugid  Only commit files related to bug.

 -B bugid  Mark files with bug.

 -c    Check for valid edits before committing.

 -D    Assume all files are modified.

 -F logfile  Read the log message from file.

 -e    Keep edited files.

 -f    Force the file to be committed; disables recursion.

 -n    Do not run the module program (if any).

 -l    Local directory only (not recursive).

 -m message  Log message.

 -R    Process directories recursively.

(Specify the --help global option for a list of other help options)

***** CVS exited normally with code 1 *****

好像是CVSNT不支持这个命令选项。

 

 2005-7-20 22:12:37    找到一些东东

使用CVS进行项目开发管理

本文出自:http://www.swm.com.cn   作者:张云帆 (2001-11-06 07:00:00)

在多人共同开发一个大型项目时,源代码的维护和版本维护是一件令人头疼的事情,由于多人开发, 每个开发人员都拥有此项目的副本,所以如果要手动维护同一个文件多人的修改是十分困难的事情。 另外,可能你需要的项目的版本不是当前开发的最新的版本, 如果为了这个目的而为每一个版本 保留一个备份几乎是不可能的。Linux平台上提供了一个功能软件:CVS。众所周知,Linux的发展 得益于互联网的发展,大部分的软件都是众多开发者在互联网上共同开发的,这些软件的维护大部 分都使用CVS,例如Deban Linux的开发、KDE的开发,以及sourceforg上的开发项目。正确熟练使 用CVS是一个Linux程序员基本的素质。

CVS不仅可以维护源代码,事实上,所有的文本文件都可以使用CVS来管理,当然也可以管理 二进 制文件,只是需要特殊的命令选项罢了。

CVS把文件保存在一个名叫仓库(repository)的地方,仓库中保存的文件并不是每个版本的副本, 而是可以从任意版本回溯到初始版本的一些代码的主控信息,这样,就节省了大量的存储空间。

仓库不仅可以建立在本机上,也可以建立在网络上。另外CVS支持版本分支(tag),这样可以从 任意的版本中衍生出另外一个版本进行开发,必要时,还可以把这个分支合并到主开发分支去。

CVS需要一个名叫RCS(修订控制系统)的软件,确切说,CVS主要管理开发项目中的目录的改动, 而RCS则侧重于管理的一个文件的改变。如果要使用网络的CVS,还需要rsh或者自己内置的 cvs-server,rsh是CVS客户于服务器的通信平台,如果需要安全的信息传输,可以使用ssh, 这个可以使用CVS_RSH环境变量来指定:

export CVS_RSH=rsh 使用rsh

export CVS_RSH=ssh 使用ssh

RCS使用

在使用CVS之前,先介绍一下RCS的使用方法。

正如前面所说,RCS是针对某一个特定的文件进行管理,常用到的命令是co和ci。RCS使用当 前工作路径下的RCS目录来存储管理的文件。

ci (check in)把源代码加入到RCS源代码仓库中,每一个添加进代码库中的文件的版本是 1.1。 以后每次修改文件重新ci以后,此文件的版本递增为1.2 ,1.3.……。

co(check out)把源文件从RCS源代码仓库中取出,缺省的版本是最新的版本,如果你需要一个 指定的版本,则需要使用-r选项指定。例如:

$mkdir RCS 建立RCS源代码仓库

编辑一个文件,如hello.c

#include <stdio.h>

int main (void)

{

printf ("Hello World/n");

return 0;

}

然后把它加入到RCS仓库中:

[kerberos@power zhyf]$ ci hello.c

RCS/hello.c,v <-- hello.c

enter description, terminated with single '.' or end of file:

NOTE: This is NOT the log message!

>>the inital verion. 输入关于文件改动的信息

>> . 以.结束信息输入

initial revision: 1.1 初始版本是1.1

done

[kerberos@power zhyf]$

当文件加入到源代码仓库后,RCS会自动删除文件。

如果需要修改文件,则从仓库取出:

[kerberos@power zhyf]$ co hello.c

RCS/hello.c,v --> hello.c

revision 1.1

done

此时,取出的文件是只读的,如果需要编辑文件,需要对文件加锁取出,防止与他人编辑冲突。  

加锁取出使用-l (lock)选项。

[kerberos@power zhyf]$ co -l hello.c

RCS/hello.c,v --> hello.c 从RCS仓库中取出hello.c,仓库中的文件是以v结尾的。

revision 1.1 (locked) 指明是加锁取出

done

这时,我们就可以修改和编辑文件了。

例如:

#include <stdio.h>

int main (void)

{

printf ("Hello World/n");

printf("checkoutwithlock/n"); 添入代码

return 0;

}

[kerberos@power zhyf]$ ci hello.c

RCS/hello.c,v <-- hello.c

new revision: 1.2; previous revision: 1.1 重新加入到仓库,文件版本递增为1.2

enter log message, terminated with single '.' or end of file:

>> check out with lock and modified it .

>> .

done

如果你需要先前的hello.c,也就是1.1版本的,可以使用-r来指定取出文件的版本:

[kerberos@power zhyf]$ co -l -r1.1 hello.c

hello.c,v --> hello.c

revision 1.1 (locked) 取出1.1版本

done

可以尝试使用两次加锁取出,这时候,RCS会提示警告信息。

[kerberos@power zhyf]$ co -l hello.c

hello.c,v --> hello.c

revision 1.1 (locked)

writable hello.c exists; remove it? [ny](n) 是否覆盖当前的hello.c

如果回答n,则取出失败,回答是则覆盖当前文件

与-l相反的选项是-u,取出不加锁的文件用于工作。-f则在ci时强制覆盖RCS仓库中的文件, 在co时强制覆盖当前的文件。  

在RCS中,支持类似于宏的关键字,在ci后,这些关键字会被RCS替换成特定的信息,

如$Id$关键字:

/*$Id

*/

#include <stdio.h>

int main (void)

{

printf ("Hello World/n");

printf("checkoutwithlock/n");

return 0;

}

ci 之后,然后取出,文件将变成:

/*$Id: hello.c,v 1.3 2001/02/22 16:16:58 kerberos Exp kerberos $

*/

#include <stdio.h>

int main (void)

{

printf ("Hello World/n");

printf ("check out with lock/n");

return 0;

}

$Id$ 关键字是用文件名、版本、时间、作者 及代码性质替换,如果使用-l选项取出,在Exp后 面会加上登录用户的名称。除了$Id$关键字,RCS还支持下面常用的关键字:

$Log$ : 你所提供的修改日志信息。

$Author$ :存入该版本的作者。

$Locker$ : 该版本的加锁者

$State$ : 该版本的状态 Exp(试验版), Stabe(稳定版), Rel(发行版).缺省是Exp

$Date$ : 该版本存入的时间,使用UTC时间格式。

$Revision$ : 该版本的版本号

$RCSfile$ : RCS文件名

$Source$ : RCS全路径名

$Name$ : 取回该版本的符号名

$Header$ : 相当于$ Source $$ Revision$$Date$$Author $$State$$Locker$的组合

在UNIX/Linux下有一个diff工具可以比较两个文件的不同,rcsdiff可以在不同的版本之间比

较文件的不同,而不必取出文件,如:

rcsdiff hello.c 比较当前hello.c文件与RCS仓库中最新版本的区别。

rcsdiff -r1.1 hello.c 比较当前hello.c文件与hello.c的1.1版本的区别。

rcsdiff -r1.2 -r1.1 比较hello.c 文件的1.1版本和1.2版本的区别。

使用这个命令,可以很方便的做出任意版本之间的补丁文件。

另外,还有其他一些不常用的RCS命令,读者可以参考更详细的资料。

CVS使用

下面我们就讲一下CVS的使用和管理。

在使用CVS之前,必须要指定CVS的根路径,不像RCS是工作在工作目录下的RCS目录下。指定 CVS路径的方法有两种,一种是使用cvs-d 选项指定,如:

cvs -d /home/kerberos/cvsroot 指定/home/kerberos/cvsroot为CVS仓库的路径。

另外一种是使用CVSROOT环境变量指定(bash下):

export CVSROOT=/home/kerberos/cvsroot

无论何种方式,每当重新开启一次终端会话,CVS仓库的路径都要重新设置,你可以把以上的 后者加入到其实目录下的.bashrc文件中,这样开启一次终端会话后,不需要重新设置了(对 于其他的环境变量的设置也是如此)。如果你的CVSROOT环境变量已经存在,可以使用cvs -d  选项来指定不同于CVSROOT所指定的CVS仓库。然后初始化CVS仓库,建立CVS维护所需要的一些 文件和信息,CVS把这些信息存放在CVS仓库主目录的CVSROOT目录下。这些文件,除了modules , 其他文件都没有手动修改的必要,modules 文件定义了CVS的导出模块在CVS仓库中的位置, 这一点在从CVS仓库中导出一个深层目录时是非常方便的。

cvs init

初始化之后,我们使用cvs import来把需要进行版本维护的开发项目的目录结构导入到CVS仓 库中,如下:

建立好项目的目录结构以后,当前的testprj目录的结构是这样的:

[kerberos@power zhyf]$ tree testprj

testprj

|-- admin

|-- doc

|-- include

|-- libs

`-- src

|-- include

`-- main

7 directories, 0 files

cvs import有三个参数:第一个是这个目录树在CVS仓库中的模块名称,第二个是发布者的一个 标志,第三个是这个项目的版本标记(tag)。下面,我们把testprj导入到CVS仓库中,使用 testprj 模块名称。

[kerberos@power testprj]$cvs import testprj KERBEROS INITVER

执行命令以后,CVS会调用CVSEDITOR指定的编辑器来让你输入日志,如果CVSEDITOR没有定义, 缺省调用vi,可以使用export命令指定你自己喜欢使用的编辑器。输入日志以后,CVS把当前的 目录结构导入CVS仓库中,并且使用testprj这个模块名称,在导出文件时,就可以使用 cvs co testprj 来导出。

"/tmp/cvscVxZnW" 5L, 242C written

cvs import: Importing /home/zhyf/cvsroot/testprj/admin

cvs import: Importing /home/zhyf/cvsroot/testprj/libs

cvs import: Importing /home/zhyf/cvsroot/testprj/src

cvs import: Importing /home/zhyf/cvsroot/testprj/src/include

cvs import: Importing /home/zhyf/cvsroot/testprj/src/main

cvs import: Importing /home/zhyf/cvsroot/testprj/doc

cvs import: Importing /home/zhyf/cvsroot/testprj/include

No conflicts created by this import

看一下cvsroot目录中的结构是不是和testprj 的相同:

../cvsroot

|-- CVSROOT

| |-- checkoutlist

| |-- checkoutlist,v

| ........................... CVS的仓库信息,省略..

| ...........................

`-- testprj

|-- admin

|-- doc

|-- include

|-- libs

`-- src

|-- include

`-- main

这里testprj 模块的结构和我们自己的testprj的目录结构是一样的。

这样,当需要再次使用这些源代码时,就可以简单的使用cvs co模块名来导出目录树和文

件了。导出任意具有写权限的目录下:

[kerberos@power testprj]$ cd ..

[kerberos@power zhyf]$ rm -rf testprj 删除testprj目录

[kerberos@power zhyf]$ cvs co testprj 重新导出

cvs checkout: Updating testprj

cvs checkout: Updating testprj/admin

cvs checkout: Updating testprj/doc

cvs checkout: Updating testprj/include

cvs checkout: Updating testprj/libs

cvs checkout: Updating testprj/src

cvs checkout: Updating testprj/src/include

cvs checkout: Updating testprj/src/main

[kerberos@power zhyf]$ tree testprj

testprj

|-- CVS

| |-- Entries

| |-- Repository

| `-- Root

|-- admin

| `-- CVS

| |-- Entries

| |-- Repository

| `-- Root

|-- doc

| `-- CVS

| |-- Entries

| |-- Repository

| `-- Root

|-- include

| `-- CVS

| |-- Entries

| |-- Repository

| `-- Root

|-- libs

| `-- CVS

| |-- Entries

| |-- Repository

| `-- Root

`-- src

|-- CVS

| |-- Entries

| |-- Repository

| `-- Root

|-- include

| `-- CVS

| |-- Entries

| |-- Repository

| `-- Root

`-- main

`-- CVS

|-- Entries

|-- Repository

`-- Root

CVS在每个目录下面都建立了一个名叫CVS的目录,此外,目录的结构是一样的,事实上,

CVS目录中存放的是一些关于目录结构在仓库中的信息,Entries中包含了这些目录中的子目录, Respository包含此目录在仓库中的相对位置,ROOT包含导出的模块主目录的绝对路径。

cvs import命令只是在第一次把项目导入CVS仓库时才使用,以后如果再需要加入目录或者加入 文件,则使用cvs add 命令加入,然后使用cvs commit提交之后,文件或者目录才会真正加入到 CVS仓库中。我们可以把刚才编辑的hello.c文件拷贝到testprj/src/main/中,然后使用:

[kerberos@power zhyf]$ cvs add testprj/src/main/hello.c

cvs add: scheduling file `testprj/src/main/hello.c' for addition

cvs add: use 'cvs commit' to add this file permanently

使用cvs commit提交修改

[kerberos@power zhyf]$ cvs commit

cvs commit: Examining testprj

cvs commit: Examining testprj/admin

cvs commit: Examining testprj/doc

cvs commit: Examining testprj/include

cvs commit: Examining testprj/libs

cvs commit: Examining testprj/src

cvs commit: Examining testprj/src/include

cvs commit: Examining testprj/src/main

RCS file: /home/zhyf/cvsroot/testprj/src/main/hello.c,v

done

Checking in testprj/src/main/hello.c;

/home/zhyf/cvsroot/testprj/src/main/hello.c,v <-- hello.c

initial revision: 1.1

使用RCS管理单个文件

done

testprj/src/main/hello.c

由于CVS使用RCS管理单个文件,所以,前面我们讲的关于RCS的知识也可以用到这里,唯一不同的 是命令之前要限定是cvs,比如cvs ci, cvs co, cvs diff, 或者在导出时使用 -r 选项指定导出的 文件的版本。在源代码文件中,同样也可以使用RCS的关键字。

对于非ASCII文件,如二进制可执行文件,位图等文件,我们不能直接使用cvs add

加入到CVS仓库中,因为CVS只是基于ASCII代码比较文件的改变,所以,对于二进制文件,如果单纯使用cvs add 命令会破坏文件的完整,所在加入二进制文件时,要指定-kb参数。如果对已有文 件进行了修改,使用cvs ci, cvs commit 来提交修改。

另外一种情况是自己导出别人修改的文件,而不想覆盖自己所作的修改,可以使用cvs update命令, 这个命令会自动比较CVS仓库中文件和当前自己文件的最后修改时间来导出最新的文件。

在cvs update 和cvs ci 时,你对此的文件修改与他人发生冲突,CVS则提示你。CVS会在文件中使 用“>>>>>>” 或者“<<<<<<<”标记标出冲突的地方,你可以与他人协商手动修改这一段代码。

如果你想删除仓库中的一个文件,就要先删除本地导出的文件,然后使用cvs remove 文件名,  cvs commit来删除。事实上,CVS是不会真正删除这些文件的,如果你还想得到这些文件,只需要, 使用cvs co -r 指定删除前的版本导出就可以了。

有时候为了导出CVS仓库中的深层目录或者文件不得不输入很长的路径,这一点很讨厌,你可以导 出CVS仓库中CVSROOT目录下,修改modules文件,定义这个目录或者文件为一个模块,提交修改后就 可以直接使用cvs co 模块名 就可以导出了。

CVS的版本控制功能主要体现在tag上。标记的作用如同是同时记录了做标记时所有文件的版本,需 要的时候可以一次导出这些版本不一的文件,这常常是在项目的开发达到了一定的目标时使用的。

cvs tag 命令的参数只有一个:标记名。例如:

cvs tag RELEASE_1.0_BETA

以后,如果需要这个版本,只需要使用cvs co -r RELEASE_1.0_BETA就可以导出这个版本了。或者 使用cvs diff -r 来生成patch文件和使用cvs log -r 来查看这个版本的日志。

标记的另外一个非常重要的作用是生成分支和合并分支。

通常,我们的项目的开发到某一定的程度时,需要探索某一条开发途径是否有效,这个时候,我们 需要做一个试验,但是这个试验的分支的开发不能影响项目的主开发分支,这样,我们就可以生成一个分支开发,主开发分支也可以继续进行,两者并不冲突,将来如果证明分支开发有效,还可以把分支合并到主开发分支中。建立一个CVS分支:

cvs tag -b 分支标记名

建立分支后,并不影响当前我们从CVS仓库中的文件,需要从CVS仓库中重新导出分支BRANCH_VER:

cvs co -r 分支标记名 模块名  

这样,我们可以进行分支开发,主分支的开发也可以照常进行,如果此分支开发成功,我们可以把它与主分支合并:

cvs update -j 分支标记名

cvs commit

就可以把开发分支合并到主分支中去了。

以上是本地CVS仓库的操作,如果使用网络CVS仓库,只需要使用CVS_RSH环境变量指定通信shell,另外设置CVS仓库为网络仓库就可以了。网络上的CVS仓库的服务器有两种:ext和dserver。对于后者在进行 CVS操作时,需要先login验证用户。后者使用rlogin验证,不需要显式登陆。如:

ext CVS 服务器使用

export CVSROOT=:ext:kerberos@power:/home/repository  

或者cvs -d :ext:kerberos@power:/home/repository

cvs co platoon

derser CVS 服务器使用

export CVSROOT=:pserver:anonymous@anoncvs.kde.org:/home/kde

cvs login  

cvs co kdebase

其他一些常用的cvs 命令选项

-d 指定CVS仓库的路径

-zn 使用gzip 压缩后传输,到本地后自动解压。n为压缩级别通常式 1~4,通常使用于服务器的传输速度较慢的情况下。

-x 用于服务器的通信使用加密算法,只有在使用kerberos验证体系下有效

cvs的配置和使用

本文出自:http://xfocus.org/   作者:san小许 整理(san@xfocus.org) (2001-09-10 08:00:00)

首先要严正声明一下,文章的前一部分很多是拷贝粘贴自linuxforum里的帖子,如果有侵犯了你的著作权,去找quack的律师谈谈:)  

cvs是一种版本控制系统,它不同于一般的版本控制系统,它可以实现版本的并发管理,即可已有多个用户同时改动同一个文件而不会互相影响,然后不同的用户将它们各自修改的文件提交到cvs服务器上,有cvs来进行文件之间的比较,进而把这些不同的部分按照某种算法进行合并形成一个新的版本。  

cvs服务器一般架设在unix系统上,虽然也有可以在Windows上运行的服务器版本,但是其性能表现远不如在unix上面表现的好, 但是cvs的客户端在Windows下却可以工作的很好。我在这里讲简单地介绍一下在 Linux下配制cvs服务,以及在Windows下客户端的设置情况。  

首先我们先说一下如何在Linux上设置cvs服务,绝大多数的Linux发行拌种都包含了cvs,如果你的发行版 本中没有或者你向是用最新的cvs版本,你可以到http://www.cvshome.org去取得最新的服务器版本,这里讲述的是以1.10版为基础的,   它应该适合更新的版本.  

如果你是从http://www.cvshome.org上的到的.tar.gz形式的源代码版本,参照源代码中的相关的说明文件,安装指导来编译程序,然后进行安装,如果你是用Linux发行版中的cvs包进行安装,执行相应的包管理工具。比如在Redhat中你可以是用下面的命令来安装cvs.    

rpm -ivh cvs-1.10.8-3.i386.rpm  

在安装完成后,我们就可以进行相应的配置。一般cvs是用pserver的认证方式作为一种服务在Linux上运行,先要确定系统里/etc/services文件有cvs服务的入口,一般得有以下两行:  

cvspserver 2401/tcp # cvs client/server operations  

cvspserver 2401/udp # cvs client/server operations  

cvs服务是通过inetd或者是xinetd来启动的。对于inetd,修改/etc/inetd.conf,添加以下的句子:  

cvspserver stream tcp nowait root /usr/bin/cvs    cvs --allow-root=/cvsroot pserver  

由于在较新的Linux发行版(如:RedHat7.x)中都是用新xinetd代替了inetd,要用xinetd来启动cvs服务你需要进入到/etc/xinetd.d/目录,然后编辑一个文本文件(名字随意),这里是用cvspserver作为文件名,这个文件的内容如下所示:  

service cvspserver  

{  

    socket_type = stream  

    wait = no  

    user = root  

    env = HOME=  

    server = /usr/bin/cvs  

    server_args = --allow-root=/cvsroot pserver  

}  

注意上面的service后面的名称一定要和你在/etc/service文件中的cvs服务名称一样,在server_args行我们指定了cvs使用pserver认证方式,可能容易产生误解的是env = HOME=这一行,添加这一行的目的就是为了解决在执行一些cvs操作时产生的读取/root/.cvsignore文件的错误,上面env那行的意思就是在运行cvs服务的时候将环境变量HOME置空,这样虽然执行cvs的用户是root,但是由于没有了HOME这个环境变量,所以cvs就不会在去读取/root/.cvsignore文件了。  

到这里我们就配置完了cvs的启动所需要的文件,但是要使cvs正常运行还需要对需要使用cvs的用户进行设置,下面是我在配置cvs是使用的方法。首先建立一个用户组cvs,可以使用groupadd或者addgroup命名,也可以直接编辑/etc/group文件添加这个组,然后添加一个用户cvsroot, 然后修改/etc/passwd文件使cvsroot用户的缺省组是cvs组,而不是cvsroot组。建立/cvsroot目录,然后修改/cvsroot的属主及属性:  

#chown cvsroot.cvs /cvsroot  

#chmod 755 /cvsroot  

(原文这里是771,但是我们要配置cvsweb.cgi,下面再谈)。  

对cvs进行初始化:cvs -d /cvsroot init  

这样cvs服务器就可以使用了,用cvs -d :pserver:cvsroot@host:/cvsroot login登陆,输入cvsroot用户在服务器上的口令,没有出现错误提示就表示成功了。  

下面讲述Windows下客户端的配置,我只会用wincvs,觉得很不错,不用记那些繁琐对命令:)可以从http://www.cvshome.org找到相应的下载地址,在linuxforum也有下载,3M多一点。启动wincvs在Admin菜单中选择preferences然后在global页中设置CVSROOT,就是:pserver:cvsroot@host:/cvsroot。在认证方式中选择passwd   file on the cvs server, 在下面的版本号中选择合适的版本,执行Admin菜单中的login,在提示框输入口令,如果Output窗口出现以下提示:  

*****CVS exited normally with code 0*****  

就表示我们现在可以在Windows下使用cvs服务了。我开始不知道成功了,还满大街的问wincvs怎么了:(英文好就看wincvs自带的帮助文挡,我也推荐两个文档:)  

wincvs.pdf winhtml.zip  

特别是这个pdf文档确实不错,还是中文的:)  

如果你想在网页里给大家显示你的项目,那么cvsweb是一个不错的选择。这是一个perl程序,可以到以下地址找到最新版:  

http://stud.fh-heilbronn.de/~zeller/cgi/cvsweb.cgi    

现在的版本是1.93,记得要用新版,1.8以下有一个小小的漏洞,可以到绿盟查一查。  

由于是cgi程序,是以nobody用户执行的,所以/cvsroot的属性要设成775。开始我按章照搬,把属性改成771,结果项目的目录就是不出来,埋葬了半天的青春:(还有记得把/cvsroot/CVSROOT/history的属性改成666。cvsweb.conf里%CVSROOT数组的Configuration设成/cvsroot,就是cvs仓库的路径不要那个长长CVSROOT变量。这些其实在它的说明文档和程序注释里都讲到了,只是这个世界是懒人的世界:)  

一切都阳春白雪,可以埋头写程序了?只是cvs还有一个小小的DoS漏洞要跟大家说一下:(  

每个cvs的操作过程会以操作用户的身份在/tmp下临时建一个锁定了的目录cvs_servPID,这时如果有人建了大量的同类文件就会使cvs的操作出错,会提示:  

cannot change permissions on temporary directory  

Operation not permitted  

下面是测试的perl程序:  

#!/usr/bin/perl  

#$min和$max的值根据实际情况修改  

$min=400;  

$max=4000;  

for ($x=$min;$x<=$max;$x++) {  

        open CVSTMP, ">>/tmp/cvs-serv$x" or die "/tmp/cvs-serv$x: $!";  

        chmod 0600, "/tmp/cvs-serv$x";  

        close CVSTMP;  

}  

解决方法:  

使用server.c中的mktemp(3)函数或者其它任何可以产生唯一文件名的方法。在/tmp/目录所在的分区使用空间配额也能解决部分问题。  主要还是扎紧篱笆,莫让别人闯进来,这毕竟是一个local的问题。  

 

CVS 速成班

http://www.linuxforum.net   何伟平 (2001-04-21 17:54:50)

结合文档和一些网上资源,折腾了半天终于搞定了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.

也希望大家能够不断补充这篇文章,最后能够成为手册,而不仅仅是速成.当然,还要更多地参考别的文档.

 

 2005-7-23 12:40:47    更换CVSNT版本出现的问题

原来是先安装了CVSNT 的最新版,配合WINCVS 1.3中文版,发现个别命令出错(如递交强制版本号时).

于是到CVSNT的官方网站下载了CVSNT 的推荐版本,里面带有WINCVS,想来应该是配合得比较好的.

于是卸载原有的CVSNT和WINCVS,安装新下载的东东. 可是发现问题更多了:

除了登录CVSNT服务器,其它所有命令都不对,我导入一个项目时,还提示莫个目录不存在. 于是打开CVSNT的控制器,重新设定CVSROOT(仓库),再启动服务,仍是出错.

后来打开注册表,发现原来版本的注册表内容可能造成了干扰,于是全部删除这些项,重新设置CVSROOT(仓库),再启动CVSNT服务,在WINCVS中导入项目,一切正常!

 

 2005-8-28 21:48:19    关于 CVS 用户账号问题

今天在XP 上重装了CVSNT和TortoiseCVS,配置好CVSNT后,用TortoiseCVS一直无法取出模块

登录时提示输入用户名和密码。我的系统用户名是中文,密码是空的,一直无法登录。

后来我添加了一个英文名的用户,用这个英文用户名登录,问题马上解决了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值