分类: LINUX
2010-06-01 18:17:30
一、获取与安装
CVS(Concurrent Versions System)是一款开源的版本控制系统,当前版本1.11.22,可以从下载。我下载的是Windows版本。下载文件cvs-1-11-22.zip后,解压到指定文件夹,我解压到了C:\CVS文件夹下。
下面在环境变量中做两个配置:
Path=C:\CVS
CVSROOT=:local:e:\cvs
对于Path的配置无需解释,最常见的了。但CVSROOT要说明一下:local,表示用local协议访问CVS,而非常见的pserser协议,pserver协议表示从客户端访问服务器,而local表示访问本地;e:\cvs,要访问的CVS仓库,该文件夹可以暂不创建。
二、常用操作
创建CVS仓库的命令:
cvs -d e:\cvs init
其中-d是cvs命令的参数,用于指定路径,此时CVS会在e:\cvs文件夹下创建一个仓库。仓库用来保存提交到CVS中的文件,并记录相应版本信息。如果e:\cvs文件夹没有创建,CVS会自动创建。
导入与拆出文件。要将文件夹导入CVS仓库,请先在命令行中定位到该文件夹下,我的文件夹为F:\project1,然后执行命令:
cvs import -m "firstProject" project vendor init
其中-m是import子命令的参数,用于记录操作日志,当前步骤的操作日志为“firstProject”,其它cvs命令如无特殊说明,-m参数也是同样含义。此时CVS会将F:\project1文件夹导入,并在仓库中生成project模块。下面在命令行中执行“cd..”命令,退往上一级文件夹,即F:下,然后执行命令:
cvs checkout -d project1 project
此时project模块与文件夹F:\project1就关联到一起了。
不过将cvs checkout操作简单地说成关联是不正确的,这一步操作应当称为拆出文件,其作用是将保存在CVS仓库中的文件取出,存放到指定文件夹下以供编辑。例如在F:下新建一个与project1同级的文件夹project2,然后执行命令:
cvs checkout -d project2 project
此时project模块也会被取到F:\project2中。下面将利用F:\project1和F:\project2文件夹来模拟两个用户的操作。
添加文件和文件夹。下面在F:\project1文件夹下新建文件1.txt,这是一个文本文件,然后在命令行中定位到该文件夹下,执行命令:
cvs add 1.txt
cvs commit -m ""
此时1.txt文件就会被添加到CVS仓库中了。这里注意,commit子命令是用来向CVS仓库提交修改内容的,以后每次文件有所变化都应用该命令向CVS执行提交。
在 CVS中,文件被分为两种类型,一种是文本文件,例如.txt、.java、.c等,一种是二进制文件,例如.exe、.doc、.xls等,这两种文件在CVS中的管理方式是不同的。下面在F:\project1文件夹下新建文件2.doc,这是一个Microsoft Office Word文件,属于二进制文件,然后执行命令:
cvs add –kb 2.doc
cvs commit -m ""
此时2.doc文件也被添加到CVS仓库中了。
下面在F:\project1文件夹下再新建一个文件夹dir,然后执行命令:
cvs add dir
此时文件夹dir同样会被添加到CVS仓库中。
更新文件和文件夹。下面在命令行中定位到F:\project2文件夹下,此时的F:\project2是个空文件夹,没有任何内容。执行命令:
cvs update -d
文件1.txt、2.doc和文件夹dir都被下载到F:\project2中了。其实cvs update的作用是更新本地文件,记得以后每次修改文件之前,都执行一次该命令。注意,如果不加-d参数,CVS只会下载文件。
提交与更新文件。下面打开F:\project1中的1.txt文件,修改、保存并关闭,然后在命令中定位到该文件夹下,执行命令:
cvs commit -m "edit 1.txt"
此时对1.txt所作的修改会被提交到CVS仓库中。如果想放弃修改,则可以在提交之前执行命令cvs update -C,此时1.txt会被恢复成修改之前的内容,同时生成.#1.txt.1.1文件以备份修改内容。
下面再打开F:\project2中的1.txt文件,发现内容没有改变,关闭,在命令行中定位到该文件夹下,执行命令:
cvs update
再次打开F:\project2\1.txt文件,会发现内容已经发生了变化,与F:\project1\1.txt文件一样。
处置修改冲突。下面分别修改F:\project1\1.txt和F:\project2\1.txt文件,注意保证两者内容的不一致,然后首先用cvs commit -m ""提交F:\project1\1.txt,再提交F:\project2\1.txt,此时CVS会提示有冲突。这是因为我们对同一个文件作了不同的修改所致,这种情况在日常使用中会经常发生。要解决这个问题,请先在命令行中定位到F:\project2下,执行命令cvs update,此时CVS将更新1.txt文件,把有冲突的部分以格式:
<<<<<<< 1.txt
F:\project2\1.txt文件冲突部分内容
=======
F:\project1\1.txt文件冲突部分内容
>>>>>>> 1.3
标记出来,并生成.#1.txt.1.2文件,以记录更新之前的F:\project2\1.txt。下面重新修改F:\project2\1.txt,执行命令cvs commit -m "",至此问题解决。关于.#1.txt.1.2文件,删除好了。
当然,我们也可以选择放弃修改,即在处理掉F:\project2\1.txt的冲突部分之后,执行命令cvs update -C,此时F:\project2\1.txt会被恢复成修改之前的内容,而.#1.txt.1.2文件则重新生成,以备份修改内容。
文件和文件夹的查看与比较。先在命令行中定位到F:\project1下,执行cvs update命令,然后陆续执行以下命令并观察其效果:
cvs status 查看project模块下所有文件和文件夹的状态
cvs status 1.txt 查看1.txt文件的状态
cvs status dir 查看dir文件夹的状态
cvs log 查看project模块下所有文件和文件夹的日志
cvs log 1.txt 查看1.txt文件的日志
cvs log dir 查看dir文件夹的日志
cvs diff 1.txt 若保存在本地的1.txt文件被修改,则与保存在CVS文件夹中的原始拷贝比较差异
cvs diff -r1.3 1.txt 用保存在本地的1.txt文件与保存在CVS仓库中的1.txt文件的特定版本比较差异
cvs diff -r1.3 -r1.4 1.txt 比较CVS仓库中1.txt文件两个版本间的差异
文件的删除。先在命令行中定位到F:\project1下,删除文件2.doc,然后执行命令:
cvs remove 2.doc
cvs commit -m ""
此时F:\project1\2.doc文件就被从CVS仓库中删除了。如果嫌麻烦,也可以使用remove子命令的-f参数,即在定位到F:\project1时执行命令:
cvs remove -f 2.doc
cvs commit -m ""
这样CVS会自动将2.doc文件删除掉的。
不过CVS并未提供删除文件夹的功能,一般情况下可以先将要删除的文件夹清空,即使用cvs remove命令删除文件夹下的所有文件,然后执行命令:
cvs checkout -P -d project1 project
即对checkout子命令使用-P参数,该参数会将工作目录下的所有空文件夹清除。如果还想保留某些空文件夹,可以再执行命令:cvs update -d 文件夹1 文件夹2,该命令会下载指定的文件夹。
文件的恢复。在CVS中,文件的恢复可以分为两种情况,一种是删除文件但未提交,以F:\project1\1.txt文件为例,先在命令行中定位到F:\project1下,然后执行命令cvs remove -f 1.txt,此时可以使用命令cvs add 1.txt进行恢复。另一种是删除文件且已提交,以之前删除的F:\project1\2.doc文件为例,执行命令:
cvs add 2.doc
cvs commit -m ""
此时F:\project1文件夹下便多了个2.doc文件。其实在CVS中,文件并不会真的被删除,而是被放到Attic目录下统一管理了。
文件的重命名与移动。CVS并未提供重命名或移动文件的功能,但我们可以通过add和remove子命令来实现。以F:\project1 \2.doc文件为例,先在命令行中定位到F:\project1下,执行cvs update -d命令,然后将2.doc改名为3.doc,再执行命令:
cvs remove 2.doc
cvs add 3.doc
cvs commit -m ""
此时2.doc就被改名为3.doc了。下面将3.doc移动到dir文件夹下,然后执行命令:
cvs remove 3.doc
cvs add dir/3.doc
cvs commit -m ""
此时3.doc就被移动到dir下了。
分支(branch)。假定软件K的发行版1.0已完成,而你正在继续开发下一版本,并计划在一段时间后发行版本1.1。可是不久你的客户就开始抱怨说K 1.0有问题,于是你检出了1.0的发行版,找到了这个错误。但是,当前代码的版本正处在一个不稳的状态,并且在一段时间之后才有希望稳定下来,这样就没法基于最新源代码去发行一个修复错误的版本了。这种情况下可以去为所有构成K 1.0发行版的文件创建版本树的一个分支。然后你可以修改这分支而不影响到主干。当修订完成时,你可以选定是否要把它同主干合并或继续保留在这个分支里。
创建分支。先在命令行中定位到F:\project1下,执行命令:
cvs tag -b new_project
此时CVS会在仓库中为project模块打上标签new_project,则new_project分支创建。
标签(tag)。即符号修订号,用来为特定版本打印标签,打印标签后即为该版本创立了分支。
获取分支。先在命令行中定位到F:\project2下,执行命令:
cvs update -r new_project
此时CVS会将new_project分支下载到F:\project2中。如果想下载之前的版本也可以利用该命令,例如:
cvs update -r 1.3
在不同分支下修改文件。下面分别修改F:\project1\1.txt和F:\project2\1.txt文件,注意保证两者内容的不一致,然后使用cvs commit -m ""进行提交。这两个文件均会被正确提交,而CVS也并未因为两者内容不一致提示版本冲突,只是提示的版本信息有所不同,这说明之前创建分支已经成功。
合并分支。在命令行中定位到F:\project1下,执行命令:
cvs update -j new_project
或
cvs update -j 1.5 -j new_project
前者是用new_project分支与本地文件做比较;后者则是用主分支的最新版本1.5与new_project分支做比较。由于之前分别修改了 F:\project1\1.txt和F:\project2\1.txt,并且刻意保证了两者内容的不同,因此在将new_project分支合并到主分支时,CVS会提示冲突,此时CVS将更新1.txt文件,把有冲突的部分以格式:
<<<<<<< 1.txt
F:\project1\1.txt文件冲突部分内容
=======
F:\project2\1.txt文件冲突部分内容
>>>>>>> 1.4.2.1
标记出来,并生成.#1.txt.1.5文件,以记录更新之前的F:\project1\1.txt。下面重新修改F:\project1\1.txt,执行命令cvs commit -m "",如果提示错误请执行cvs update -A,再重新提交。如果想放弃,则可以在修改1.txt文件后,执行命令cvs update -C,此时1.txt会被恢复成修改前的内容,而.#1.txt.1.5文件则重新生成。注意,new_project分支不会因为与主分支的合并而消失。
标签管理。在命令行中定位到F:\project1下,执行命令:
cvs tag -b forTest
为主分支打上标签,创建新的分支。
噢,不好意思,其实我是想为1.txt文件的1.5版本创建分支,而当前版本是1.6,搞错了。怎么办呢?执行命令:
cvs tag -r 1.5 -F -B forTest 1.txt
这样标签就会被移动到版本1.5上了。如果想直接在版本1.5上创建分支,请执行命令:
cvs tag -r 1.5 -b forTest
嗯,现在我又不喜欢forTest作为标签的名字了,我想让标签的名字叫newTest,请执行命令:
cvs rtag -r forTest newTest project
cvs rtag -d forTest project
project是我们在import数据到CVS仓库时创建的模块名。第一条命令执行之后,newTest会替换forTest;但forTest作为标签却并未真正消失,因此使用第二条命令将其删除。
此时我又不想建立分支了,执行命令:
cvs rtag -d newTest project
标签newTest被删除。
固定文件版本。之前的一系列操作导致CVS仓库中文件的版本十分混乱,可以使用命令:
cvs commit -m "" -r 1.7
将所有文件的版本固定到1.7。注意,文件版本只能固定成更高的版本,而无法固定成低版本。
标明模块不再使用。在命令行中定位到F:\project1下,执行命令:
cvs release -d .
或在F:\下执行命令:
cvs release -d project1
此时F:\project1目录下的所有内容被清空。
导出。在命令行中执行命令:
cvs export -D2007/06/18 -d F:\project project
此时版本库中所有在2007年6月18日之前生成的内容均会被导出到F:\project文件夹中,如果不指定-d参数则会被导出到当前路径下。注意,F:\project会自动生成,并且该文件夹中的内容比较干净,不包含版本控制信息。
生成补丁。在命令行中定位到F:\project1下,执行以下任意一条命令:
cvs diff -c -r 1.7 -r 1.3 1.txt > test.diff(在1.txt的两个指定版本间比较)
cvs diff -c -r 1.3 1.txt > test.diff(在1.txt的当前版本与指定版本间比较)
cvs rdiff -r 1.7 -r 1.3 . > test.diff(在当前模块的两个指定版本间比较)
cvs rdiff -r 1.3 . > test.diff(在当前模块的当前版本与指定版本间比较)
会生成输出信息到文件test.diff中。这些版本间的差异信息被称为补丁,而test.diff文件则称为补丁文件。注意,当不写“> test.diff”时,例如cvs diff -c -r 1.7 -r 1.3 1.txt,信息会直接输出到屏幕。关于diff与rdiff命令的差异,前者比较的对象是文件,后者比较的对象是模块。
三、子命令同义词
在CVS中,一些子命令是有同义词的,通过同义词可以简化操作,例如commit子命令的同义词为ci,这样就可以将命令:
cvs commit -m ""
简化为:
cvs ci -m ""
下面列出了前面用到的几个子命令的同义词:
checkout:co,get
commit:ci
rdiff:patch
四、update子命令的输出
在执行update或commit子命令的过程中,会看到一些标志性的字母,那么这些字母表示些什么呢?
A 在工作副本中添加文件并将这一操作更新到CVS仓库
R 在工作副本中删除文件并将这一操作更新到CVS仓库
U 更新工作副本中不存在或者没有修改过的文件
P 与U类似,但是以补丁的形式更新
C 有冲突
M 合并成功
? 工作副本中存在而CVS仓库中不存在的文件