您的当前位置:首页正文

CVS建立软件配置管理环境

来源:个人技术集锦
建立软件配置管理环境(cvs)

1. 安装CVS服务器 1.1 windows环境 1.1.1 下载

由www.cvsnt.org下载到CVSNT的安装程序。 1.1.2 安装

在服务器端执行下载得到的安装程序,进行CVSNT安装。

Windows XP and 2003注意:某些系统的WMI 服务可能会引起访问拒绝错误。为了避免这种情况的发生,安装前必须停止WMI服务,安装完成后重新启动WMI服务。

Start Screen:

License Agreement:

Install Directory Selection:

Antivirus Software Warning:

Install Component Selection Screen:

Shortcut Folder Selection Screen:

Task Selection Screen:

Ready To Install!:

Install Progress:

Installation Done!:

注意:如果遇到有关genkey.exe错误,并且安装成功,但是SSL key 没有生成;因此sserver protocol 不能正确工作。

1.1.3 系统重新启动

第一次安装CVSNT后必须重新启动系统,否则当你建库时将会发生“Repository initialization failed”错误。

1.1.4 创建CVS目录

在CVS服务器创建两个目录,例如:c:\\cvsrepo和c:\\cvstemp。 目录必须建立在NTFS盘上。

C:\\cvstemp 由SYSTEM的所有用户控制。

Cvstemp目录不能建立在c:\\WINNT\\Temp或c:\\Documents and Settings。

在server 创建一个名称为“CVSUsers”的组,并添加属于这个组的所有CVS 用户。

1.1.5 CVSNT控制面板配置

打开控制面板并找到CVSNT applet (绿色的鱼):

启动下列插图applet:

注意:如果发生问题可能的原因是系统的一些dll丢失。这些文件需要从CVSNT网站直接下载。

可能丢失的文件是: mfc71.dll mfc71u.dll msvcp71.dll msvcr71.dll msvci71.dll

将它们拷贝到 C:\\WINNT\\System32 folder.

现在执行CVSNT applet 并按下列步骤做:

核实service 不在执行(Start 按钮被启动)。如果service 已经启动,则停止它。下列是初始屏幕:

转到\"Repositories\"标签,看下图:

现在选择Repository Prefix 框,并点击省略钮浏览目录c:\\cvsrepo。

导航选择c:/cvsrepo。对话框如下图:

注意:设置CVS库的前缀(prefix),不能直接使用硬盘驱动器,必须到目录树的顶层(象:c:/cvsrepo)。

点击“Add”按钮增加一个库。在出现的对话框内输入“test”,点击“OK”按钮创建库,在同一个服务器内可创建多个库。

转到Advanced 标签并查看下图的设置框:

有两个选项可供你设置和清除。(对大多数用户使用缺省设置):

点击省略号按钮设置temp目录,设置为c:\\cvstemp。

 现在点击“Apply”按钮。

1.1.6 启动CVSNT

回到第一个标签并点击”“Start”按钮:

1.1.7 增加CVS用户

使用pserver或sserver协议需要本节,并且要增加的用户名不是NT用户表的部分。如果所有的用户是windows用户,建议使用SSPI,它与Windows NT 结合比较好,如果决定使用SSPI,可以跳过本节中增加和管理用户的讨论。所有:sspi:用户必须是有效的用户不能使别名。

打开命令窗并按下列做:

Set cvsroot=:sspi::/TEST

Cvs passwd -r -a

为该用户输入一个密码,并输入两次。现在CVSROOT/passwd文件将被创建并且该用户被加入到文件中。

重点注意:

用户必须是在“local”系统的一个NT用户!CVS不接受任何用户注册即不能连接到一个“real”用户。但可以以“alias”通过下述命令注册到一个“real”用户:

Cvs passwd –r -a 如果用户名有空格,必须有双引号括起。 注意2(Domain 用户):

可以以下列命令添加domain用户:

Cvs passwd –D –a

增加一个用户(必须是domain的真实用户)到passwd文件并通知CVSNT检查pserver/sserver口令。注意:CVS服务器必须是domain的一个成员!

1.1.8 测试CVS连接

打开另一个命令窗口并输入: 1.1.8.1 pserver,sserver,ssh

Set cvsroot=::@:/TEST 用有效值替换,例如: Set cvsroot=:pserver:Charlie@cvsserver:/TEST 然后注册: Cvs login 1.1.8.2 sspi

Set cvsroot=:sspi::/TEST 用有效值替换,例如: Set cvsroot=:sspi:cvsserver:/TEST 现在可以输入: Cvs ls –l –R

将给出TEST/CVSROOT目录下的文件清单。 使用WinCvs(ver 1.3):

这一步骤执行如下: Authentication: sspi Path: /TEST

Host address: User name:

然后注册(如果用“pserver”): Admin/Login

在WinCvs的命令窗中输入: Cvs ls –l –R

得到与上述相同的结果。 例如:

cvs -z9 login

Logging in to :pserver:bosse@castor:2401/test

*****CVS exited normally with code 0***** cvs ls -l -R

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

Listing modules on server

Directory CVSROOT

checkoutlist 1.1 Sat Mar 16 23:22:16 2002 commitinfo 1.1 Sat Mar 16 23:22:16 2002 config 1.1 Sat Mar 16 23:22:16 2002 cvswrappers 1.1 Sat Mar 16 23:22:16 2002 editinfo 1.1 Sat Mar 16 23:22:16 2002 loginfo 1.1 Sat Mar 16 23:22:16 2002 modules 1.1 Sat Mar 16 23:22:16 2002 notify 1.1 Sat Mar 16 23:22:16 2002 rcsinfo 1.1 Sat Mar 16 23:22:16 2002 taginfo 1.1 Sat Mar 16 23:22:16 2002 verifymsg 1.1 Sat Mar 16 23:22:16 2002

1.1.8 具有管理库权限的用户

 

在库的CVSROOT目录中创建一个名为“admin”的正文文件。 在文件的一行单独增加用户的注册名。例如:

charlie jennifer

john

现在这些用户可以使用,用cvs admin 命令可以改变它们的密码。

1.1.9 封闭多余的协议

如果CVSNT服务器暴露在Internet下,因安全的原因你可以要求封闭:pserver:协议。 在CVSNT服务器封闭任何协议通常使用的方法是:从CVSNT程序目录删除相应xxx_protocol.dll文件。

1.1.10 管理pserver用户

如果你计划使用pserver用户,你可以按下列要求做:

以“cvsuser”名在CVSNT服务器创建一个本地用户。 使用系统管理帐户注册到cvs服务器。

用下列命令为“cvsuser”添加一个别名作为注册名: Cvs passwd –r cvsuser –a

1.1.11 用SSPI协议访问CVSNT

SSPI跨TCP/IP工作,所以它更容易穿越防火墙。当你的工作站在启动时带有sspi协议时,就不需要用户注册。

使用sspi用户访问的限制

Sspi将接受来自所有系统用户(local or domain)的连接。通常这不是我们想要的,我们想用:pserver:一样的机制来代替。在这里CVSROOT/passwd文件限制CVSNT接受注册。

你需要在passwd文件中列有可访问CVS的用户注册名,还必须在CVSROOT/config文件设置参数

SystemAuth = No

在这种情况下不需要输入口令到passwd文件。SSPI用系统注册名和passwd文件作为可接受的用户表。当作为CVS管理者注册工作时,先使用下列命令:

Cvs passwd -a newuser

按两次回车,通知CVSNT不使用口令。

1.1.12 用户访问CVS调优

NTFS文件系统权限能被用于调整CVS库的访问权限: 创建NT用户组。

不用别名注册,用户用自己的实名注册。 使用CVS组在库中为模块级设置权限(read/write/modify,read only,no access)。 设置CVSROOT文件夹所有用户组可read,定位到库文件夹下。仅系统管理员能write/modify访问该文件夹,有两个文件例外(如下)。

设置CVSROOT/history文件为所有用户组可read/write。时每个用户可发现谁做了什么。

设置CVSROOT/val-tags文件为所有用户组可read/write,具有分支文件或文件夹的权限。

设置CVSTEMP文件夹为所有用户组可read/write。 将所有成员设置为CVS用户组。

检出你库的CVSROOT,并编辑config文件,它包括下列行: LockServer=localhost:2402

用控制面板的applet重新启动CVSNT 服务。

1.2 Linux环境 1.2.1 安装CVS

绝大多数的Linux发行拌种都包含了cvs,如果你的发行版本中没有或者你向是用最新的cvs版本,你可以到http://www.cvshome.org去取得最新的服务器版本。

如果你是从http://www.cvshome.org上的到的.tar.gz形式的源代码版本,参照源代码中的相关的说明文件,安装指导来编译程序,然后进行安装,可以使用下列命令:

# unzip cvs-x.xx.x.tar.gz # tar xvf cvs-x.xx.x.tar # cd cvs-x.xx.x # ./configure # make

# make install

如果你是用Linux发行版中的cvs包进行安装,执行相应的包管理工具。比如在Redhat中你可以是用下面的命令来安装cvs. rpm -ivh cvs-1.10.8-3.i386.rpm

1.2.2 配置CVS

1.加入CVS服务

vi /etc/services

cvspserver 2401/tcp #pserver cvs service

cvspserver 2401/udp #pserver cvs service 2.设置启动CVS服务

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

加以下的句子:

cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/home/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=/home/cvsroot pserver }

注意: 1)上面的service后面的名称一定要和你在/etc/service文件中的cvs服务名称一样, 2)pserver表示是口令认证的访问方式,这是最常用的方式,其他还有

gserver,kserver,ext,如果想要更高的安全性可以使用ssh来加密口令和数据流。

3)--allow-root是指定Repository的目录,可以建立多个Repository,例如: server_args = --allow-root=/home/cvsroot1 -- allow-root=/home/cvsroot2 pserver 4)可能容易产生误解的是env = HOME=这一行,添加这一行的目的就是为了解决

在执行一些cvs操作时产生的读取/root/.cvsignore文件的错误,上面env那行的意思就是在运行cvs服务的时候将环境变量HOME置空,这样虽然执行cvs的用户是root,但是由于没有了HOME这个环境变量,所以cvs就不会在去读取/root/.cvsignore文件了。 3.重新启动inetd或者xinetd

/etc/rc.d/init.d/xinetd restart

4.检查cvspserver服务是否已经启动

netstat -l |grep cvspserver 结果如下:

tcp 0 0 *:cvspserver *:* LISTEN

1.2.3 建立用户

1.建立CVS用户组

groupadd cvs

2.建立cvs组的cvsroot用户和所属的目录

useradd -g cvs -G cvs –d /home/cvsroot cvsroot 3.为cvsroot用户添加密码

passwd cvsroot

4.改变/home/cvsroot的目录属性

chmod 775 /home/cvsroot

1.2.4 在CVS服务器端建立Repository

1.初始化cvs源码库,此操作生成目录/home/cvsroot/CVSROOT,其下为一些初始化文件 cvs -d/home/cvsroot init

为了CVS系统的安全,我们要修改/home/cvsroot/CVSROOT/config文件,将\"#SystemAuth =no\"的前而的注释号#去掉,即改为“SystemAuth =no” 2.创建可以登陆cvs服务的用户及密码:

给开发者们逐一建立账号,新建的不要分配用户目录,因为它将作为一个虚拟用户帐号来使用,具体命令如:

# useradd -g cvs -M trotter # passwd trotter

# useradd -g cvs –M gary # passwd gary

# useradd -g cvs –M mimi # passwd mimi

上面的命令就创建了一个并没有Home目录的用户,接着将系统的shadow文件复制到CVSROOT, 并重命名为passwd:

#cp /etc/shadow /home/cvsroot/CVSROOT/passwd #chmod 0644 /home/cvsroot/CVSROOT/passwd trotter:*****:***:**: mimi:*****: ***:**: gary:*****: ***:**:

然后修改passwd文件,将除刚才设定的可使用CVS的用户之外的所有行删除,然后去掉每行第二个冒号以后的所有内容,并添上字符串cvsroot, 改为如下格式: trotter:*****:cvsroot mimi:*****:cvsroot gary:*****:cvsroot

然后,删除掉刚刚在系统中添加的用户 #userdel -f trotter #userdel -f mimi #userdel -f gary

1.3 Unix环境 1.3.1 安装CVS

从http://www.cvshome.org上的到的.tar.gz形式的源代码版本,参照源代码中的相关的说明文件,安装指导来编译程序,然后进行安装,可以使用下列命令:

# unzip cvs-x.xx.x.tar.gz # tar xvf cvs-x.xx.x.tar # cd cvs-x.xx.x # ./configure # make

# make install

1.3.2 配置CVS

1.加入CVS服务

vi /etc/services

cvspserver 2401/tcp #pserver cvs service

cvspserver 2401/udp #pserver cvs service 2.设置启动CVS服务

cvs服务是通过inetd来启动的。对于inetd,修改/etc/inetd.conf,添加以下的句子: cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver 3.重新启动

4.检查cvspserver服务是否已经启动

netstat –a |grep cvspserver 结果如下:

tcp 0 0 *:cvspserver *:* LISTEN

1.3.3 建立用户

1.建立CVS用户组

groupadd cvs

2.建立cvs组的cvsroot用户和所属的目录

useradd -g cvs -G cvs –d /home/cvsroot cvsroot 3.为cvsroot用户添加密码

passwd cvsroot

4.改变/home/cvsroot的目录属性

chmod 775 /home/cvsroot

1.3.4 在CVS服务器端建立Repository

1.初始化cvs源码库,此操作生成目录/home/cvsroot/CVSROOT,其下为一些初始化文件 2.创建可以登陆cvs服务的用户及密码:

给开发者们逐一建立账号,新建的不要分配用户目录,因为它将作为一个虚拟用户帐号来使用,具体命令如:

# useradd -g cvs -m trotter # passwd trotter

# useradd -g cvs –m gary # passwd gary

# useradd -g cvs –m mimi # passwd mimi

上面的命令就创建了一个并没有Home目录的用户,接着将系统的shadow文件复制到CVSROOT, 并重命名为passwd:

#cp /etc/shadow /home/cvsroot/CVSROOT/passwd #chmod 0644 /home/cvsroot/CVSROOT/passwd trotter:*****:***:**: mimi:*****: ***:**: gary:*****: ***:**:

然后修改passwd文件,将除刚才设定的可使用CVS的用户之外的所有行删除,然后去掉每行第二个冒号以后的所有内容,并添上字符串cvsroot, 改为如下格式: trotter:*****:cvsroot mimi:*****:cvsroot gary:*****:cvsroot

然后,删除掉刚刚在系统中添加的用户 #userdel trotter #userdel mimi #userdel gary

1.4 Aix环境 1.5 Solaris环境

2. 安装CVS客户端 2.1 windows环境

本文以WinCVS (ver 1.3.6.1 beta 6)为例来说明cvs的使用方法。 2.1.1 准备工作 2.1.1.1 术语

Update---从cvs服务器下载新版本文件。当本地文件比服务器上的还新时,update将失败。 Commit---将本地更新过的文件提交到cvs服务器。如果本地文件比服务器上的还旧,commit将失败。

Import Module---将本地模块建立到服务器上(即在服务器上新建一模块)。 Checkout Module---从服务器上取出一个模块。 2.1.1.2 准备目录

在使用CVS之前,要在你的电脑上建立一个空目录,主要用来存入cvs的系统信息,也可以用来存放从CVS服务器下载出来的文件。将这个目录命名为CVSHOME。 2.1.1.3 安装

请到http://sourceforge.net/projects/cvsgui 下载WinCVS 1.3安装程序。下载完后执行setup.exe,按提示安装即可。

安装完后, 启动WinCvs,就可以看到主画面了。 主画面分为五个区域:

1. 菜单---提供WinCvs的全部操作命令。 2. 工具条---提供常用的操作命令。 3. 树形菜单---目录浏览。 4. 文件清单---文件视图。

5. 控制台---命令执行的信息输出窗口,你也可以直接在里面输入cvs命令。

2.1.2 设置

2.1.2.1 设置常规选项

打开\"Admin\"菜单,点击\"Preferences\"子菜单。在\"General\"页中,设置与cvs服务器有关的选项:

a.设置\"Authentication\"(认证方式),选择\"pserver\"。 b.设置\"Path\"(cvs服务器上的仓库根目录)。 c.设置\"Host address\"( cvs服务器名)。

d.设置\"User name\"(用户名),输入个人的cvs帐号,即Win2k Server的帐号。 e.设置\"CVSROOT\"参数,这是cvs专用的参数格式,如下所示: username@servername:path

其中username是帐号,servername是服务器名,path是cvs服务器上的仓库根路径。

2.1.2.2 设置全局选项

a.\"Checkout read-only\"选项是设置当文件从服务器上check out出来后是否要设成唯读。

2.1.2.3 设置WinCvs选项

a.\"Default viewer used to open files\"选项设置预设的文件查看器。

\"Use on double click\"选项设置当鼠标在文件上双击时,是否使用上面选项所设置的查看器打开。通常不要选择这项,让它用文件相关的程序打开。 b.\"External diff program\"选项设置外挂的文件比较程序。

c.\"Home folder.(where cvs stores your passwords)\"选项设置CVSHOME参数的目录。它是wincvs用来存放cvs登入密码的地方,将此目录设为先前建立的CVSHOME目录即可。

2.1.3 登入

点击\"Admin\"菜单,再点击\"Login…\"菜单,

之后出现一个password对话框,

输入密码,即可登入CVS服务器。登入后,wincvs将自动记住你的密码,下次使用wincvs时,可以不用人工登入。

下面是登入后,wincvs控制台输出的信息:

其中第一行是登入命令,第二行是登入信息,第三行是登入成功后返回的代码。通常看一个cvs的命令是否执行成功,可以看这个返回代码是否为0,否则此命令执行不成功。

2.1.4 新建模块

我们来看一下如何在cvs服务器上新建一个模块

假设在本机的CVSHOME目录中有一个demo目录,此目录中有相关的源代码或是其它的文件。我们要将这个目录作为一个模块(Module),建立到cvs服务器上去。通常服务器上已建立好了一个CVSROOT目录,专门用来存放模块用的。

现在启动WinCvs程序,在窗口左边的树形目录中找到上面所示的目录位置。如果在这里找不到这个目录,可以点击\"View\"菜单,再点击\"Browse Location\",进入\"Change\"菜单,如下图,

这时出现对话框,找到demo目录所在的位置,点击\"确定\"即可。

这时,WinCvs的树形目录切换到了demo目录。在demo目录上点击鼠标右键,进入\"Import Module\"子菜单,这时出现下面的对话框:

选择demo目录,这时,wincvs自动识别出demo中所有文件的类型。所下图,

一般源代码等是TEXT格式的,而其它如图片,OFFICE文档等是二进制格式的。如果你发现WinCvs列出的格式与实际的格式不符,可以在相应的项目上双击来修改格式。 完成后按对话框上的\"Continue\"按钮,出现下面的对话框,

设置Module的名字为\"demo\",Vender tag和Release tag分别是制造和发行标记,可根据需要设置。在log message中设置一个日志信息,可以将来用作追踪用。 按\"确定\"按钮后,wincvs即开始执行import命令,并输出下图信息,

我们看到绿色是提交到服务器\"demo\"模块中的新文件。最后命令结果返回0,表示命令执行成功,已经在服务器上建立了一个demo模块,并且包含了所有的文件。 成功后你即可将本机的demo目录删除了。下面要来讲解如何从cvs服务器check out一个模块。

2.1.5 Checkout模块

在WinCvs左边的树形目录上点击鼠标右键,进入\"Checkout Module\"菜单,出现下面的对话框,

输入你要checkout的模块的名字(注意大小写),即demo,再输入checkout下来后的存放目录,按\"确定\"按钮,这时,在WinCvs的控制台输出以下信息,

表示命令执行成功。这时,在WinCvs左边的树形目录中也多了一个demo的目录。相应的

文件也在里面。

2.1.6 update和commit文件

如果文件内容有改变,应即时的提交到服务器上。现在我们修改一个demo目录中的readme.txt文件,储存后,文件的图标即变成了红色,表示此文件被修改过,如下图,

这时,在此文件上点击鼠标右键,再点击\"Commit selection…\"菜单,出现下面的对话框,

输入log message后按确定即可。这时,控制台的输出信息如下,

表示命令执行成功。如果命令执行失败,可能是另外有人修改了这个文件并提交到了服务器。即服务器上的版本可能比你现有的文件还新,这时你有三种选择: a. 将服务器上的文件和本地的文件合并后再提交

先在文件上点击菜单命令\"update…\在弹出的对话框上什么都不要选,点击确定按钮,执行后,控制台输出下面的信息:

合并后的文件前面有一个M标记。 b. 用本地的文件将服务器上的文件覆盖

在文件上点击菜单命令\"commit…\在出来的对话框上切换到Commit options页,选择Force commit,如下图,

按确定,命令执行后,控制台输出下面的信息,

其中可以看到文件版本从1.2变到了1.3. c. 用服务器上的文件将本地文件覆盖

在文件上点击菜单命令\"update…\在出现的对话框中选择Get the clean copy,如下图,

按确定,命令执行后,控制台输出以下信息,

更新过的文件为绿色,前面标有U标记。同时,WinCvs会自动在此文件的当前目录备份更新前的文件,文件名前面会加上\".#\",后面会加上版本号。如上面的readme.txt文件会备份为\".#readme.txt.1.4\"。

2.1.7 Add文件

如果在本机目录中新建了文件,必须用Add命令将它添加到cvs服务器。 假设我们在demo目录中新建了一个newfile.txt目录,如下图,

这个文件的图标显示为问号形式,并且在status栏也显示为\"NonCvs file\",表示这个文件还没有纳入cvs管理。 要将此文件加入到Cvs,请先选择它(如有多个文件,可以多选),点击\"Modify\"菜单中的\"Add selection\",如果是二进制文件,点击\"Add binary\"菜单,命令执行后,控制台的输出信息如下,

返回代码为0表示命令执行成功。执行后文件前的图标变为红色,cvs就认为这是修改过的文件,你还必须用前面提到的Commit方法将文件提交到cvs服务器。

2.1.8 Remove文件

如果要将cvs中的文件删除,不能简单的将它从本机目录中删除,而必须借助Remove命令。不然的话,当你下次Checkout module时,在本机删除的文件又从服务器下载下来了。 假设我们现在要从cvs中删除newfile.txt文件。请先选择此文件(如有多个文件,可以多选),点击\"Modify\"菜单,再点击\"Remove\"菜单命令,这时控制台的输出信息如下,

这时此文件已被做了删除标记,文件前的图标变为红色。

如要真正的从cvs服务器上删除此文件,还必须再执行一次commit命令。

2.1.9 Remove空目录

在WinCvs中只提供了删除文件的功能,如要删除一个目录,必须先将这个目录中的文件用上面介绍的方法清空,然后再在WinCvs的树形菜单中选中你要删除的目录的上层目录,将光标移到控制台窗口中,输入以下命令: cvs update –P

完成后再执行一次update命令,即完成删除。

2.1.10 cvs命令

除了用菜单命令外,你也可以在WinCvs的控制台中直接输入cvs的命令来执行。如要学习更多的cvs命令,可以在http://sourceforge.net/projects/cvsgui中找到相关的帮助。

2.2 Linux环境 2.2.1 安装CVS

绝大多数的Linux发行拌种都包含了cvs,如果你的发行版本中没有或者你向是用最新的cvs版本,你可以到http://www.cvshome.org去取得最新的服务器版本。

如果你是从http://www.cvshome.org上的到的.tar.gz形式的源代码版本,参照源代码中的相关的说明文件,安装指导来编译程序,然后进行安装,可以使用下列命令:

# unzip cvs-x.xx.x.tar.gz # tar xvf cvs-x.xx.x.tar # cd cvs-x.xx.x # ./configure # make

# make install

如果你是用Linux发行版中的cvs包进行安装,执行相应的包管理工具。比如在Redhat中你可以是用下面的命令来安装cvs. rpm -ivh cvs-1.10.8-3.i386.rpm

2.2.2 配置CVS环境

export CVSROOT=:pserver:username@ip:/home/cvsroot

这样你在客户端就可以直接输入 cvs login登陆了,其它操作都可以直接cvs command 了。

2.2.3 登入

cvs login

2.3 Unix环境 2.3.1 安装CVS

从http://www.cvshome.org上的到的.tar.gz形式的源代码版本,参照源代码中的相关的说明文件,安装指导来编译程序,然后进行安装,可以使用下列命令:

# unzip cvs-x.xx.x.tar.gz # tar xvf cvs-x.xx.x.tar # cd cvs-x.xx.x # ./configure # make

# make install

2.3.2配置CVS环境

export CVSROOT=:pserver:username@ip:/home/cvsroot

这样你在客户端就可以直接输入 cvs login登陆了,其它操作都可以直接cvs command 了。

2.3.3 登入 Cvs login

2.4 Aix环境 2.5 Solaris环境

3. cvs操作 3.1 建立项目

1.从外部引入项目

进入外部项目所在的第一级目录用cvs import命令将该项目引入cvs。 Cvs import porj zjft rel_1_0

把该目录下的所有子目录和文件放到$CVSROOT/proj,并以rel_1_0为版本号,以zjft为开发商名。

2.创建全新项目

如果没有任何源文件,创建一个项目目录,并加入到CVS中,然后在该目录下创建文件。

Mkdir zjcns Cd zjcns

Cvs import proj zjft START 3.2 在项目中添加新的目录和文件

在项目的工作目录创建此目录或文件,用cvs add 通知cvs准备加入文件。 Cvs add log.c

然后,用cvs commit执行添加操作: Cvs commit log.c 3.3 定义模块

cvs支持在逻辑上把一组目录、文件组成一个项目,用一个模块来定义它。模块可以包含子模块。模块概念大大方便了项目管理。

1.登出modules文件

Cvs checkout $CVSROOT/modules 2.模块定义

有三种基本类型的模块定义格式: --别名模块 --正则模块 --连接符模块

在下述的例子中,库的顶级有一个目录first-dir,该目录下有两个文件file1、file2和一个目录sdir,sdir目录下有一个文件sfile。

别名模块:

模块的最简单格式。 mname -a aliases...

mname是模块名,aliases可以包括模块名或路径名。 例如:

amodule -a first-dir

下面的两个命令是等价的: $ cvs co amodule $ cvs co first-dir

它们的输出是一样的:

cvs checkout: Updating first-dir U first-dir/file1 U first-dir/file2

cvs checkout: Updating first-dir/sdir U first-dir/sdir/sfile

正则模块:

mname [ options ] dir [ files... ] 最简单的格式是mname dir。它定义在目录dir下的所有文件作为模块mname。Dir是CVS库中相对于$CVSROOT的路径。在这种情况下checkout,一个名为mname的目录将作为工作区目录被创建。

例如:

regmodule first-dir

即regmodule将包含first-dir下的文件:

$ cvs co regmodule

cvs checkout: Updating regmodule U regmodule/file1 U regmodule/file2

cvs checkout: Updating regmodule/sdir U regmodule/sdir/sfile $

在模块定义的dir后,有明确地说明具体文件,例如: regfiles first-dir/sdir sfile

regfiles模块将创建目录regfiles其中包含定义中的文件:

$ cvs co regfiles

U regfiles/sfile $

连接符(&)模块:

一个模块通过在定义中包括&module格式,参照其他的模块。 mname [ options ] &module

然后,模块创建一个目录,在目录中包含&module中定义的模块。 例如:

ampermod &first-dir

checkout将创建一个ampermod目录,其中包含子目录first-dir。 例如:

$ cvs co ampermod 将创建下列文件:

ampermod/first-dir/file1 ampermod/first-dir/file2

ampermod/first-dir/sdir/sfile

排斥目录

一个别名模块,可以用“!”排斥其他模块中的部分目录。 例如:

exmodule -a !first-dir/sdir first-dir

checkout时,模块exmodule将checkout first-dir中的任何文件,除了first-dir/sdir子目录的文件。

模块任选项:

正则模块和连接符模块包含任选项: -d name

命名工作目录相当于模块名。 -e prog

只要模块中的文件被输出(export),程序prog将运行。prog带单个参数运行,即模块名。

-i prog

只要模块中的文件被提交(commit),程序prog将运行。prog带单个参数运行,即在源库中受影响目录的全路径名。

-o prog

只要模块中的文件被checkout,程序prog将运行。prog带单个参数运行,即模块名。

-o prog

只要模块中的文件被用rtag加标签,程序prog将运行。prog带两个参数运行,即模块名和rtag说明的符号标签。

3.登入模块定义

$ cvs commit modules

4.发布模块定义 $ cd ..

$ cvs release -d CVSROOT

3.4 制定版本

1.版本编号

为方便版本识别和管理,要对版本编号。版本编号分为系统编号和用户编号:

 系统编号是CVS自动给版本编的号码。CVS自动管理系统编号,单分支

版本演化以1.0->1.1->1.2->….的方式顺序进行。向项目添加新文件时,其版本号第一位同本目录最高版本第一位,第二位是1。例如:

一个目录下三个文件版本号分别为1.5、2.8、4.11,则新文件版本号

为4.1。  用户编号是用户为了自己控制版本号码,或者统一版本号码,而对某一

版本指定的编号。指定的版本号必须大于所有当前版本号。例如下述命令将所有源文件统一为5.0版本:

Cvs commit –r 5.0

2.版本标签

版本标签是符号化的版本号码,它直观且易于记忆和管理。版本标签大量用于重要的里程碑式版本的标记。例如alpha初始条式版、beta调试版、release发布版等。

--标签的设定:

用tag命令给文件的当前工作版本一个标签,如下述命令将文件acctd.c的当前工作版本指定为REL_0_4版。

Cvs tag REL_0_4 acctd.c T acctd.c

注意:很少有人会单独给一个文件指定一个版本标签。 --版本标签的查看:

Cvs status –v acctd.c

====================================== File: acctd.c status :up-to-date ………… Existing tags;

REL_0_4 (revision:1.1) --里程碑版本标签的设定:

在项目通过一定标准的测试之后,可是设定特定的里程碑版本标签。例如:标记当前对应仓库中的版本为alpha 1.0 的命令是:

Cvs tag ALPHA_1_0 Cvs tag: taggin T acctd.c T log.c T trans.c T usradmin.c

--CVS标记何处文件:

注意!cvs tag操作发生在仓库中被登出的版本,而不是在当前的工作目录中的工作版本。可以使用下述命令,让cvs在两者发生不一致时告警。

Cvs tag –c REL_1_0

Cvs tag: Makefile is locally modified

Cvs [tag aborted]: correct the abve errors first! --指定标记何版文件

按日期或版本号莱标记(cvs rtag)

-D date 选项标记在该日期之前的最近版本。 -R tag标记含有tag版本标签的文件。

-F 只与上述两个选项配合使用,让cvs在找不到匹配的版本时,不是忽略某文件,而是使用该文件的在仓库中的最新版本。例如:

Cvs rtag –D 20010410 BATA_2_1 acct

上述命令将acct模块中所有文件在截至2001年4月10日的最新版本标记为BETA_2_1。

3.5版本分支与合并

版本分支是用户在一个主要的版本序列上导出的一个辅助版本序列。分支版本与主版本序列并存,可以进行并行开发。如果需要,分支版本可以合并到主版本中。

通常情况下,文件的版本号呈线性增长: 1.1 –〉1.2 –〉1.3 –〉1.4

在多分支情况下,文件的版本号构成一个版本树:

1.2.2.3.2.1

分支1.2.2 1.2.2.1 1.2.2.2 1.2.2.3

1.1 1.2 1.3 1.4 1.5

分支1.2.4 1.2.4.1 1.2.4.2 1.2.4.3

引发版本分支一般有以下几个原因:

1. 设想1.0发布版已经上市,1.5版正在开发,突然客户抱怨1.0发行版中

的一个致命错误。开发小组登出1.0发行版找出这个bug,并且找到了修补办法。1.5开发版正在调试,短时间内根本不可能发布修正这个bug的1.5发布版。因此在1.0发布版的基础上分出1.0fix版,修补bug发布1.0补丁版,并合并1.5开发版。

2. 公司需要开发5个不同UNIX平台上的产品。这5个产品的共同部分已

经完成,余下的产品特性在各平台有所差异,分出5个版本分支,独立并行开发。

3. 公司产品需要对6个大客户进行定制,他们的需求各有不同。可以在产

品发布版上分出6个版本分支,独立并行开发

版本分支和合并的工作步骤:

1. 创建分支

创建分支有两种情况:一种是直接创建,一种是登出一个版本后创建。 直接创建:

使用cvs rtag命令,不参考任何版本拷贝,直接创建分支: Cvs rtag –b –r REL_1_0 REL_1_0_PATCH acct

在acct模块的1.0发行版上创建分支。参数-r REL_1_0指示cvs将分支基于REL_1_0版本,而非当前的最新版本。

注意:在创建版本分支之后,并不能立即访问使用版本分支,因为版本分支创建在cvs仓库中,而非当前工作目录。 登出一个版本后创建:

登出一个版本后,使用cvs tag 创建分支。 Cvs co –r REL_1_0 acct

Cvs tag –b REL_1_0_PATCHES Cvs tag:tagging T acctd.c T log.c T transc.c T usradmin.c

当前这个分支中的所有文件与1.0发行版完全相同。 注意:分支创建在仓库中,不影响当前工作版本。

2. 访问版本分支

创建一个新目录,从仓库中登出版本分支: Mkdir src Cd src

Cvs co –r REL_1_0_PATCHES acct Cvs checkout : updtating acct U acct/acctd.c U acct/log.c U acct/transc.c U acct/usradmin.c

或者,从当前工作版本切换到分支版本,并且将当前工作版本中的所作的

所有修改合并到分支版本。

Cvs update –r REL_2_0_PATCH acct 或者: cd acct

Cvs update –r REL_2_0_PATCH

3. 查看当前分支

使用cvs status命令查看当前工作在哪个版本分支,看sticky tag的状态: Cvs status –v acctd.c file: acctd.c status : up-to-date ….

Sticky tag. REL_1_0_PATCHES(branch 1.1.1.1.2) Sticky date: (none) Sticky options: (none) ……..

4. 合并一个完整的分支

使用cvs update –j branch 合并分支:

将从分支的基部到分支的最新版本所作的全部修改合并到工作版本中,原来的工作版本都保留在以.#开头的文件中,不会丢失,例如:

1.1 1.2 1.3 1.4 1.5

分支R1-PATCH 1.2.2.1 1.2.2.2

假设当前工作版本是在主分支上,登出本树主分支上的最新版本1.4: Cvs co acct

把1.2到1.2.2.2之间的变动合并到工作拷贝中: Cvs update –j R1-PATCH Cvs update: updating ……

Merging differences between 1.4 and 1.2.2.2 into acctd.c

只要两个新版本的修改不冲突,合并的版本就包含两者的修改。在不同位置添加,合并结果两者都被添加;在不同位置删除,合并结果中两者都被删除;在不同位置更改,合并结果将包括两者的改动。

当两种修改发生冲突,即两者修改了原版本中的统一代码时,合并结果将显示这些冲突。例如:

版本1.4 版本1.6 在1.4版基础上的当前修改版 #include #include #include Void main(){ int main(int argc,char *argv[]){ #include Parse(); Parse(); Void main(){ If(nerr==0) if(argc!=1){ init_scanner(); Gencode(); fprintf(stderr,”no argc Parse(); Else expected.\\n”); If(nerr==0)

Fprintf(stderr,”no code exit(1);} Gencode(); Generated\\n”); If(nerr==0) Else

Exit(nerr==0?0:1); Gencode(); Fprintf(stderr,”no code } Else Generated\\n”);

Fprintf(stderr,”no code Exit(nerr==0? Generated\\n”); EXIT_SUCCESS: Exit(!!nerr); EXIT_FAILURE); } } 合并后的冲突显示: #include #include

int main(int argc,char *argv[]){ init_scanner(); Parse(); if(argc!=1){

fprintf(stderr,”no argc expected.\\n”); exit(1);}

If(nerr==0) Gencode();

Else Fprintf(stderr,”no code Generated\\n”); <<<<<<Exit(nerr==0? EXIT_SUCCESS: EXIT_FAILURE); ========== Exit(!!nerr); >>>>>>>1.6 }

3.6 添加、删除、重命名

1.添加文件和目录 登出源代码

在登出源代码的目录下创建这个文件/目录 Cvs add filename 通知cvs准备添加 Cvs commit filename 执行添加操作

要添加多个文件/目录,只需罗列在命令之后,如: Cvs add file1 file2 file3 2.删除文件

删除前应确认所有对文件的修改都已经登入CVS仓库。文件删除后,用户仍可以从CVS仓库中登出老版本。 方法一:

从工作目录中删除文件,如: Rm log.c

通知cvs准备删除该文件: Cvs remove log.c

从cvs仓库中删除文件:

Cvs ci –m “removed from project” log.c

方法二:

让cvs删除工作目录下的文件拷贝,并准备从仓库中删除: Cvs remove –f log.c 从仓库中删除文件:

Cvs ci –m “removed from project” log.c

3.删除目录

与文件相似,目录被删除后,仍然能够访问到该目录的老版本。要删除一个目录,需要先删除目录中的所有文件,使该目录为一个空目录,然后运行cvs update –P让cvs从仓库中清除空目录:

Cvs remove –f *.tcl

Cvs remove –m “remove test dir” Cvs update -P

4.访问被的删除文件和目录

从cvs仓库中登出旧版本,例如1.1版: Cvs update –r 1.1 log.c

如果忘记了文件版本号,即使这个文件已不存在于当前的工作目录之中,仍可以用log查看其历史:

Cvs log log.c

如果连文件名都忘记了,可以用cvs log -R来查看所有的文件,包括被删除的文件。

5.移动和重命名文件

将工作目录中的旧文件重命名为新文件: Mv old new

通知cvs删除旧文件: Cvs remove old 通知cvs添加新文件: Cvs add new

从cvs在仓库中删除旧文件,添加新文件: Cvs ci –m “name old to new” old new

3.7 查看历史纪录

每次登入一个文件的时候,必须写日志信息,否则CVS拒绝登入。每个版本均有日志信息,用户可以访问日志信息的全部历史纪录。

1.查看历史纪录

查看日志信息使用cvs log 命令,例如: 查看acctd.c文件的全部日志:cvs log acctd.c

查看acctd.c文件1.2版的日志:cvs log –r 1.2 acctd.c 2.用户自定义日志

用户可以让cvs以多种方式记录种种动作,这一功能是通过在不同的时候执行脚本程序完成的。脚本程序需要用户自己编程完成。

脚本程序可以向日志文件添加一条消息,向一组开发者发送电子邮件,向新闻组发布消息。

记录登入动作,使用loginfo配置文件。

分别记录登入、登出、输出和版本标签,在modules配置文件中使用-i,-o,-e,-t选项。 更直接的通知其他用户的方法是cvs watch add命令。

Taginfo配置文件用于定义当有人执行tag或者rtag命令的时候要执行的程序。 文件格式为正则表达式后跟命令,传给命令的参数依次是标签明、动作、仓库、文件版本(如果有的话)。

例如:

在taginfo文件中写入:

ALL /src/master/CVSROOT/loggit Loggit脚本程序包含如下代码: #!/bin/sh

Echo “$@” >>/home/jyan/src/acct/taglog 3.使用annotate命令

annotate命令可用于查看文件每一行的最后一次修改时间、修改者、添加/修改时文件的版本号。这个命令不报告哪些被删除或者替换的行,这些内容可以用cvs diff来看。

例如:

$ cvs annotate acctd.c Annotation for acctd.c

*******************************

1.1 (admin 27-mar-99): #include 1.2 (jyang 28-mar-99): int main(void){}

在这个例子中,acctd.c现在包含两行代码,第一行由admin在3月27日登入,第二行由jyang在3月28日登入。

3.8 处理二进制文件

1.Cvs对文件的加工

Cvs仓库中使用UNIX文件格式。如果客户端是windows,cvs将进行回车换行与回车之间的转换。cvs要在文件中搜寻关键字序列,并进行替换扩展。

2.二进制文件的问题

重要的二进制文件也要进行版本管理。例如:编译器、运行环境、web图片等。 二进制文件必须原封不动保存在cvs仓库中,上述两项转换必须禁止。 cvs无法完成二进制文件的版本合并,为此,应该避免版本分支。 3.保存二进制文件

使用-kb选项来禁止cvs对文件进行加工,如下命令将二进制文件binfile加入仓库: Cvs add –kb binfile Cvs commit binfile 4.恢复方法

如果意外忘记使用-kb选项登入了一个二进制文件,可以使用如下方法恢复,如果这个文件是binfile:

UNIX环境:

Cvs admin –kb binfile 恢复仓库中的文件 Cvs update –A binfile 更新当前工作文件 WINDOWS环境:

拷贝完好文件到当前目录执行, Cvs admin –kb binfile Cvs commit binfile 5.让cvs识别二进制文件

cvs能够根据文件名来识别哪些文件时二进制文件,例如:.exe文件。cvs 无法根据文件内容识别二进制文件。Cvswrappers匹配文件定义如何根据文件名区别对待不同文件。

6.Cvswrappers的匹配

cvs允许用户根据文件名控制文件处理的配置。在cvswrappers文件中定义。 文件格式如下:

Wildcard [option val] [option val] …. Option可以是:

-m 更新方式 val:MERGE/COPY -k 关键词扩展 val:b/o/kkv/c 例如:

*.exe -k „b‟

*.doc -m „COPY‟

3.9 协同开发

较大的软件项目都需要小组协作开发。小组协作中的同步、冲突解决、通信,如果没有辅助工具,团队效率将大打折扣。Cvs提供协作同步、冲突辅助解决、通信功能,大大提高团队效率。

1.使用Cvs协作开发的注意要点: 协作中的同步:

更新、合并文件。

协作中的冲突:

文件状态冲突。 多人同时运行cvs。 协作中的通信:

监视谁在修改文件。 Cvs通知。

查看谁在编辑文件。 查看谁在监视文件。 编辑被监视的文件。 协作中的若干决策: 是否要锁定登出。

选定最适当的登出约束方案。 何时登入。

2.查看文件状态

文件被登出后,依据自己对文件的操作和其他人对文件的操作不同,文件可能处于一系列不同的状态,cvs status命令报告文件的状态: Up-to-date,与仓库中最新版本一致。 Locally modified,已修改但未登入仓库。 Locally added,已用add加入但未登入仓库。

Locally removed,已用remove删除但未登入仓库。 Needs checkout,有人修改,但你未登出。 Needs patch,与上面相似但cvs只发补丁。

Needs merge,他人登入新版本,你也做了修改。

File had conflicts on merge,与上面相似,但上一个update命令产生过冲突。

Unknown(?),cvs对本文件一无所知。

Cvs status命令用于查看文件状态,命令报告working revision和repository revision前者是当前所登出的版本,后者是当前仓库中最新的版本。例如: Cvs status –v log.c

3.更新和合并文件

Cvs update这一命令取出cvs仓库中的最新版本合并到当前工作版本中。用户对文件的改动永远不会因为使用update命令而丢失。如果没有更新的版本,该命令无任何效果。如果该文件正被修改,cvs将把所有的改动合并到工作拷贝中。例如:

Cvs update acctd.c 4.多人同时运行cvs

多人同时运行cvs时,只有一人能成功,其他人全得到类似如下的消息: [10:23:50] waiting for zhaoxg‟s lock in /master/src/cvsroot/foo

Cvs将每30秒再试,直到成功或被终止。这是因为cvs要用锁保护内部数据。 如果cvs被锁定不正常的时间,则看看是谁在运行什么cvs命令,并让他终止。典型的情况是有人在运行cvs命令后,正在写log信息;或如无人运行,到$CVSROOT/CVSROOT中删除以“#cvs.lock”,“#cvs.rfl”,“#cvs.wfl”为名字开始的文件。

5.监视谁在修改文件

为了更好的协调开发工作,开发者或者管理者可能想知道谁在对文件进行操作。Cvs提供监视功能:

Cvs watch on [-lR] files …

迫使用户运行cvs edit后才能修改files(不要用操作系统的命令来变更cvs文件的读写属性)。如果参数files包含目录名,cvs将监视其中的所有文件。以后加到其中的文件也将被监视。

Cvs还提供了关闭监视功能: Cvs watch off [-lR] files …

登出时不生成只读文件,cvs不提示使用cvs edit和cvsunedit命令。选项“-l”使命令只限于本目录不包括子目录。选项“-R”覆盖~/.cvsrc文件中的“-l”选项,使命令包含所有子目录。

6.请求cvs通知

Cvs能通知用户发生在文件上的多种操作: Cvs watch add [-a action] [-lR] files …

当有人操作文件时,cvs查表决定通知哪些用户。此命令将当前用户加入文件相应的表中。

-a 选项取值

Edit/unedit/commit/all/none:对应 Cvs edit/unedit/commit等命令。 取消通知请求使用命令:

Cvs watch remove [-a action] [-lR] files …

7.cvs通知的配置

如果有任何通知要求,cvs将调用配置文件中的notify文件。Notify文件遵循配置文件的通用格式:由若干行reg-expr command对组成。Command应包含%s变量,表示被通知的用户名(Cvs 不通知本人)。如:

ALL mail %s –s “cvs notification”(使用户得到电子邮件通知)

如果不配置,通知只发到cvs服务器所在的机器上。如果想让cvs发到其他地址,

管理员需要在$CVSROOT下创建users文件,其中每行是一个“user:value”对。例如: Xiaozhao: xzhao@xxx.com Xiaowang: xwang@yyy.com Dali: dli@zzz.org

用户可以配置cvs,让cvs在自己登入的时候将这个操作通知他人。

Moudles文件中的-i选项定义源代码被登入时被调用的程序。例如,以下配置让模块acct的每次登入都触发/usr/bin/inform.pl程序,参数为仓库中被影响的目录路径: acct –i /usr/bin/inform.pl %s project/acct

Loginfo文件用于控制cvs commit的日志信息发送到何处。

8.编辑被监视的文件

被监视的文件在登出时成为只读文件,无法直接编辑,要编辑这个文件用cvs edit 例如:

Cvs edit [options] files …

把文件变成可读写,并通知那些请求得到通知的用户,使用与cvs watch add相同的参数。本命令为监视文件的用户建立一个临时监视器,执行unedit或者commit命令后,监视器将被取消。

要放弃对文件的修改,使用cvs unedit: Cvs unedit [-lR] files

放弃本文件所作的修改,回到修改前的版本,把文件变回只读状态。通知要求监视本操作的用户。

如果没有任何监视器,本命令不能执行,要回到原来的版本,应删除该文件,并

使用cvs update来完成。

查看谁在监视文件的命令是:

cvs watchers [-lR] files …

列出正在监视files变化的用户,cvs报告被监视的文件和每个监视器的邮件地

址。

查看谁在修改文件的命令是: Cvs editors [-lR] files ….

列出正在编辑files的用户。Cvs报告各编辑者的邮件地址、开始时间、以及他们工作的主机名和文件在主机上的路径。

9.登出

锁定登出(Reserved checkouts)不允许其他用户修改被登出的文件。使用命令:cvs admin –l 。对于word文档,函数库等二进制文件无法由cvs合并,应当选择锁定登出。如果选择非锁定登出,在登入的时候cvs会试图合并,将会造成不良后果。

非锁定登出(unreserved checkouts)是cvs缺省方式,允许其他用户修改被登出的文件。Cvs不会告知第一个登入者是否还有人在修改文件,其他人要登入时会得到错误信息,他们预先与仓库中的最新版本合并才能登入。对于源代码等应选择非锁定登出,否则将大大降低软件生产率。如果非锁定登出造成严重的代码冲突,那是因为开发者的沟通严重不足。 单纯的非锁定登出对于许多项目而言是可行的。锁定登出控制过于严格,不利于提高软件生产率。介于两者之间的非锁定登出与监视机制结合,对许多小组是最佳选择。它既允许其他用户修改文件,又给予监视者以了解动态能力。

10.登入

如果登入过于频繁,也许还没有编译通过就已经登入了。这样,其他人更新时,将会导致无法编译的错误。如果登入过于稀疏,其他人不能从你的改进中获益,而且会有更多的冲突发生。需要设定一定的登入标准,让开发者在合适的时机登入。

通常,大多数开发小组要求登入前必须编译通过,这可以通过配置commit info配置文件来实现。有的开发小组还要求登入前必须通过一个测试包,但过于严格的控制可能会降低软件的生产率,所以要三思而行。

3.10 仓库

Cvs仓库是cvs系统用于储存源代码等软件资源的内部数据库。

1.仓库的备份

如同备份一组目录、文件一样简单易行,与备份普通文件不同的是,备份操作前后及过程中cvs不能运行,可采用下列方法之一:

备份过程不使用cvs,即禁止登录cvs服务器,或关闭cvs服务器。 让备份程序锁住cvs,即在每个仓库目录下创建“#cvs.rfl”锁文件。

2.仓库的移动

与备份仓库类似,需要禁止cvs使用,其他与移动一组目录、文件类似。主要的问题是用户的工作目录指向原来的仓库,需要更新:确认所有的修改都已经登入仓库,创建新的工作目录,重新设定$CVSROOT值,登出一份新的工作拷贝,删除原有的所有工作目录。

因篇幅问题不能全部显示,请点此查看更多更全内容