CVS 简单教程 CVS 是 Concurrent Version System(并行版本系统)的缩写,用于版本管理.如果大家曾经参与过多人协作开发的项目,大家肯定有这样的痛苦经历:由于多个人同时修改同一个文件,自己辛辛苦苦修改的程序被别人彻底删除了.另外,如果你的软件/程序已经发布了三个版本,而这时候用户需要你修改第二个版本的东西,也许你会因为只保留了最新版本而痛哭流涕.还有就是你对程序做了一些修改,但是修改很少,你只想给远方的同事发一个两个版本之间的差别文件,这样可以免于邮箱不够大,网速太慢之类的问题.为了解决类似这样的问题,以及诸如生成补丁文件,历史版本修改等,一帮黑客(褒义)在原先 Unix 体系里很成熟的 SCCS 和 RCS 的基础上,开发了 CVS.(SCCS:Source Code Control System,RCS:Revision Control System) CVS 的基本工作思路是这样的:在一台服务器上建立一个仓库,仓库里可以存放许多不同项目的源程序.由仓库管理员统一管理这些源程序.这样,就好象只有一个人在修改文件一样.避免了冲突.每个用户在使用仓库之前,首先要把仓库里的项目文件下载到本地.用户做的任何修改首先都是在本地进行,然后用 cvs 命令进行提交,由 cvs 仓库管理员统一修改.这样就可以做到跟踪文件变化,冲突控制等等. 由于 CVS 是典型的 C/S 结构的软件,因此它也分成服务器端和客户端两部分.不过大多数 CVS 软件都把它们合二为一了. 结合文档和一些网上资源,我写一点非常简单的“速成”的教材.希望对大家有用. 前提要求: root 权限; #groupadd cvs 生成的用户家目录在/home/cvsroot(根据自己的系统调整) 用 cvsroot 用户登陆,修改 /home/cvsroot (CVSROOT)的权限,赋与同组人有读写的权限: $chmod 771 . (或者770应该也可以) 建立CVS仓库,(仍然是 cvsroot 用户),用下面命令: $cvs -d /home/cvsroot init 以root身份登陆,修改 /etc/inetd.conf(使用 xinetd 的系统没有此文件)和 /etc/services, 说明:上面的行是单独一整行,/usr/bin/cvs 应该是你的cvs版本的命令路径,请根据自己的系统调整./home/cvsroot 是你建立的CVSROOT的路径,也请根据上面建立目录的部分的内容做调整. 如果是使用 xinetd 的系统,需要在 /etc/xinetd.d/ 目录下创建文件 cvspserver(此名字可以自己定义),内容如下:
service cvsserver
说明:cvsserver 是任意的名称,但是不能和已有的服务重名,也要和上面修改 /etc/inetd.conf 那行的第一项一致.这里我用的是 CVS 的口令认证方式,CVS 还有其他认证方式,我没有做试验,如果您有经验,请补充,谢谢. 添加可以使用 CVS 服务的用户到 cvs 组:
重起inetd使修改生效: #killall -HUP inetd
这样服务器就设置完成了.我们接着搞客户端. 设置客户端 如果是 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 登陆CVS服务器: $ cvs login,这时候 cvs 会问你口令,请把你在 CVS 服务器上的口令敲进去,这里是 laser 在 CVS服务器上的系统用户的口令: 成功登陆后将在你的家目录建立一个 .cvspass 文件,以后就不用输入口令了. 好,客户端设置完成,简单吧. 服务器可以用了,现在大家最关心的就是如何管理服务器,比如,我想让一些人有读和/或写 CVS 仓库的权限,但是不想给它系统权限怎么办呢?
passwd:cvs 用户的用户列表文件,它的格式很象 shadow 文件: {cvs 用户名}:[加密的口令]:[等效系统用户名] 如果你希望一个用户只是 cvs 用户,而不是系统用户,那么你就要设置这个文件,刚刚安装完之后这个文件可能不存在,你需要以 cvs 管理员用户手工创建,当然要按照上面格式,第二个字段是该用户的加密口令,就是用 crypt (3) 加密的,你可以自己写一个程序来做加密,也可以用我介绍的偷懒的方法:先创建一个系统用户,名字和 cvs 用户一样,口令就是准备给它的 cvs 用户口令,创建完之后从 /etc/shadow 把该用户第二个字段拷贝过来,然后再把这个用户删除.这个方法对付数量少的用户比较方便,人一多就不合适了,而且还有冲突条件(race condition)的安全隐患,还要 root 权限,实在不怎么样.不过权益之计而已.写一个小程序并不难,可以到 linuxforum 的编程版搜索一下,有个朋友已经写了一个贴在上面了. 第三个字段就是等效系统用户名,实际上就是赋与一个 cvs 用户一个等效的系统用户的权限,看下面的例子你就明白它的功能了. readers:有 cvs 读权限的用户列表文件.就是一个一维列表.在这个文件中的用户对 cvs只有读权限. writers:有 cvs 写权限的用户的列表文件.和 readers 一样,是一个一维列表.在这个文件中的用户对 cvs 有写权限. 上面三个文件在缺省安装的时候可能都不存在,需要我们自己创建,好吧,现在还是让我们用一个例子来教学吧.假设我们有下面几个用户需要使用 cvs: laser, gumpwu, henry, betty, anonymous. 其中 laser 和 gumpwu 是系统用户,而 henry, betty, anonymous 我们都不想给系统用户权限,并且 betty 和 anonymous 都是只读用户,而且 anonymous 更是连口令都没有.那么好,我们先做一些准备工作,先创建一个 cvspub 用户,这个用户的责任是代表所有非系统用户的 cvs 用户读写 cvs 仓库. #adduser 然后编辑 /etc/group,令 cvspub 用户在 cvs 组里,同时把其它有系统用户权限的用户加到 cvs 组里.(见上文) 然后编辑 cvs 管理员家目录里 CVSROOT/passwd 文件,加入下面几行: laser:$xxefajfka;faffa33:cvspub 注意:上面的第二个字段(分隔符为 :)是密文口令,你要用程序或者用我的土办法生成. 编辑 readers 文件,加入下面几行: anonymous 编辑 writer 文件,加入下面几行: laser 这样就 ok 了,你再用几个用户分别登陆测试,就会发现一切都 ok 了.这里面的原理和说明我想就不多说了,其实很简单,和系统管理用户的概念是一样的. 现在服务器和客户端都设置好了,那么怎么用呢,我在这里写一个最简单的(估计也是最常用的)命令介绍: 首先,建立一个新的CVS项目,一般我们都已经有一些项目文件了,这样我们可以用下面步骤生成一个新的CVS项目: 进入到你的已有项目的目录,比如叫 cvstest: 这里最重要的就是 Status 栏,这里总共可能有四种状态: 如果你只是想保持软件的同步的话(象我),那么上面的东西就足够用了.可是如果多人协作开发项目的话,可就不是了这么简单了.当你参加项目,维护文件时,就需要更多命令,比如说你我都是某 nasdaq 项目的开发人员: 1,你对某个文件做了修改,比如说改了ceo.c,加了一行程序:printf("where can I find VC to cheat!"); 2,当我开始干活的时候,可能我先: ================================================================== Working revision: 1.1.1.1 'Some Date' 于是我知道有人改了ceo.c,于是我就: 如果这天你修改了coo.c,加了一行 puts("how about another kind of bragging?"); 于是我知道有个狗屎在我修改文件的当口做了提交,于是我 于是我把上面改成: 然后你可以发布并删除你自己的工作目录里这个版本的文件(注意:不是删除仓库里的.): $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 3,一些小技巧: // $Header: /home/cvsroot/simhost/simhost.cpp,v 1.2 2001/04/20 08:26:10 jqliu Exp $ 一般我们把它放在开头,这样对程序员修改文件非常便利,很多时候你只要看一眼开头就知道文件是否最新. $Id$标记:把这个标记放在文件的任何地方都会被 cvs 替换成最后修改的 cvs 用户名,该文件当前版本号,最后修改时间,该文件的 cvs 仓库路径,看起来象下面这个样子: $Id: simhost.cpp,v 1.3 2001/04/24 02:27:36 simhost Exp $ 好了,上面所有的东西,估计就是我们用cvs时80%情况下用的命令和内容,包括文件的更新,提交,冲突的解决,分支的派生,增删文件等.实际上cvs的功能之强大,远远超出我在这里描述的内容,我这个"速成"也就管不了太多了,希望随着时间的推移,我们能够更加有效地使用CVS.也希望大家能够不断补充这篇文章,最后能够成为手册,而不仅仅是速成.当然,还要更多地参考别的文档. 参考资料: |
CVS 简单教程(版本管理)
最新推荐文章于 2009-02-25 17:55:44 发布
CVS 简单教程
2006年12月04日 星期一 09:35