• 5966阅读
  • 1回复

使用CVS进行版本管理zz[风中纸页] [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2005-07-30

使用CVS进行版本管理
翻译:廖斌
   
#//////////////////////////////////////////////////////////////////////
# 使用CVS进行版本管理
# 2000-6-30
# CVS 1.10.7
#
#
#
# Per Cederqvist et al 著
# 廖斌 译
# 感谢黄箐的输入和排版工作
# copyrigh: GPL
#
#//////////////////////////////////////////////////////////////////////
快捷内容索引
1. 概述.........................................................1
2. 代码仓库.....................................................7
3. 使用CVS开始一个项目..........................................29
4. 主干版本(Revision).........................................33
5. 分支与合并...................................................41
6. Recarsive behavior...........................................49
7. 增加,删除,更名文件和目录...................................51
8. 回顾开发历史.................................................57
9. 放置二进制文件...............................................59
10 多个开发者的同时工作........................................61
11 主干版本管理.............................................71
12 关键字替代................................................73
13 跟踪第三方代码...............................................77
14 你的系统如何同CVS交互........................................81
15 特殊文件.....................................................83
16 附录
1) CVS命令导向..................................................85
2) CVS命令快速参考............................................115
3) 管理文件的参考习册.........................................127
4) 影响CVS的所有环境变量......................................141
5) CVS各版本之间的兼容性......................................143
6) 遇到的问题.................................................145
7) Credits....................................................153
8) 对CVS和这本手册的总是处理..................................155
目录 ...........................................................157
1 概论
这一章为从未用过CVS的人写的,也许以前也从未用过任何版本控制工具。
1.1 什么是CVS?
CVS是个版本控制系统,使用它你可以记录你原代码文件的历史。
例如,当软件修改时有时会产生问题(*bugs这里被译为问题),并且你可能在做这
次修改后很长时间不会发现这些问题。使用CVS,你可以容易地回顾老的代码版本去
发现哪一次的修改导致这些问题。有时候这样会非常有帮助。
你可能会保留你每一次的代码版本,这可能会浪费你很多的代码空间。CVS使用一
种聪明的办法保存你的多个版本在一个文件中。它仅仅保留版本间的不同内容。如果
你是一个项目中的一组成员之一,CVS也能够帮助你。除非你特别仔细,你很容易覆盖其
他人的工 作。一些编辑器,例如GNUEmacs,试图去判定一个文件是否被两人同时修改。
不幸的是,如果一个人使用其它的编辑器时,这个安全方式将不再有效。CVS使用让不同
开发者独立工作的方式解决了这个问题。每一个开发者的工作都在他自己的目录内,并且
CVS将 在每个开发者的工作完成后进行合并工作。
CVS是由Dick Grune作为Shell脚本的一个分支而创建的,1986年10月,在它的第6个发行卷
时,它被投递到新闻组comp.soures.unix。然而现在的CVS冲突算法中没有任何代码是从这
些脚本中来的。
在1989年3月,Brian Berlinor设计并编写了CVS的代码。Jett.Polk在以后帮助 Brian 完成了CVS
模型的设计和商业版本支持。
你可以通过不同的方式得到CVS,包括在Internet上自由的下载。如果你想下载CVS和其它CVS
文章以得到更多的信息,请看:
http://www.cyxlic.com
http://www.loria.fr/~molli/cvs-index.html.
有一个叫 info-cvs 的邮件列表是有关CVS的内容。订阅或取消订阅这个列表请发邮件到
info-cvs-request@gnu.org
如果你更喜欢Usenet新闻组,CVS的讨论组为
Comp.software.confg.mgmt.
在将来也许会建一个
Comp.software.confg.mgmt.cvs
的新闻组,
但也许这会是Comp.software.confg.mgmt在有太多讨论之后的事情吧。
你也许想订阅bug-cvs的邮件列表,这在附录H[BUGS]中有更多的信息。订阅它请发Email到
bug-cvs-reqnest@gnu.org.
1.2 CVS不能做的事
(未译)
2
3 使用CVS开始一个项目
=======================
因为更改文件名并且把它们移动到另一个目录中不是经常发生的,因此你在开始一个新项
目时要做的第一件事是考虑你的文件组织。更改文件名或移动文件并非不可能,但增加了
理解上潜在的费解,并且CVS在更改名字的目录上特别的敏感。请参见7.4节[移动文件]。
(* 译者注: 在Unix中改名和移动是相同的)。
下一步做的事取决于手中的情况。
3.1 建立文件
第一步是在仓库中建立文件。这可以使用多种不同的方法来完成。
--------------------------------------------------------------------
3.1.1 建立一个目录树
当你开始使用CVS时,你可能已经有几个项目可以使用CVS进行管理了。在这种情况下,
最容易的方法就是使用: "import"命令。一个例子是最容易解释如何使用它的。假定你现
在有一些你想放到CVS中的文件在"wdir"中,并且你想让它们放在数据仓库中的如下目录:
"$CVSROOT/yoyodyne/rdir"
你可以使用如下命令:
$cd wdir
$cvs inport -m "Inported Sources" yoyodyne/rdir yoyo start
如果你没有使用"-m"参数记录一个日志信息,CVS将调用一个编辑器(*译者注:通常是vi)
并且提示输入信息。"yoyo"字符串是开发者标笺,"start"是发行标笺。他们没有什么特别
的意义,仅仅是因为CVS的需要才放在这里。
请参见第13章[跟踪代码],得到更多的这方面信息。
你现在可以检查一下它是否有效了,然后可以删除你原来的代码目录。
$cd
$mv dir dir.orig
$cvs checkout yoyodyne/dir
$diff -r dir.orig yoyodyne/dir
$rm -r dir.orig.
为了避免偶然进入到你原来的目录中去编辑文件,删除原来的代码是个好主意。当然,在
你删除之前保留一份备份到其它地方也是明智之举。
"checkout"命令能使用模块名作为参数(正如前面所有例子)或是一个相对于$CVSROOT的路
径,如同上面的例子。你应当检查CVS目录中的权限情况是否合适,应当使它们属于某一个
特定的组。请参见2.2.2.节[文件权限]。
如果你想"import"的一些文件是二进制代码,你可以使用一些特殊的方法表明这些文件是否
是二进制文件。请参见C.2节[Wrappers]。
------------------------------------------------------------------------------------
3.1.2 从其它版本控制系统建立文件
如果你有一个其它版本控制系统维护的项目,例如RCS,你也许希望把这些文件放到CVS中,
并且要保留这些文件的历史。以下是一些讨论。
从RCS:
如果你使用RCS,找到RCS文件??通常一个文件名叫"foo.c"的文件会有"RCS/foo.c,v"的RCS文
件。(但它有可能在其它地方,请看RCS的文档以得到相关信息)。如果文件目录在CVS中不存
在,那在CVS中创建它。然后把这些文件拷贝到CVS的仓库目录中(在仓库中的名字必须是带
",v"的原文件;这些文件直接放在CVS中的这个目录下,而非"RCS"子目录中)。这是在CVS中
一个为数不多的直接进入CVS仓库直接操作的情况,而没使用CVS命令。然后你就可以把它们
在新的目录下"checkout"了。
当你把RCS文件移动CVS中时,RCS文件应在未被锁定的状态,否则移动操作时CVS 将会出
现一些问题。
从其它版本控制工具
许多版本控制工具都可以输出"RCS"格式的标准文档。如果你的版本控制工具可以做到这一
点,直接输出RCS文件,然后按照上面的例子做就可以了。
如果你的版本工具不能输出RCS文件,那么你必需要写一个脚本文件来,每次取出一个版本
然后把它放到CVS中去。下面提到的"sccsarcs"脚本就是一个很好的例子。
从SCCS:
有一个"sccsarcs"的脚本文件可以做把SCCS的文件转化成RCS文件,这个文件放在CVS原代码
目录的"contrib"目录中。注意:
你必须在一台同时安装了RCS和SCCS的机器上运行它。并且,正如其它在"contrib."目录中的
其它脚本一样。(你的方法也许是变化多端的)
(*译者注:我并未查看过CVS的contrib目录:-(,因此不知道这下面都有些什么)。
从PVCS:
在"contrb"中有一个叫"pves-to-rcs"的脚本可以转换PVCS到RCS文件。你必须在一台同时有
PVCS和RCS的机器上运行它。
请看脚本中的注释以得到更多细节。
3.1.3从无到有建立一个目录树
建立一个新的项目,最容易的方法是建立一个空的目录树,如下所示:
$mkdir tc
$mkdir tc/man
$mkdir tc/testing
在这之后,你可以"import"这个(空)目录到仓库中去。
$cd tc
$cvs import -m "created directory structure"yoyodyne/dir yoyo
start
然后,当新增一个文件时,增加文件(或目录)到仓库中。请检查$CVSROOT中的权限是否正确。
-------------------------------------------------------------------------------------------
3.2 定义模块
下一步是在"moduyes"文件中定义模块。这不是严格需要的,但模块能把相关的目录和文件容易
关联起来。下面的例子可以充分演示如何定义模块。
1. 得到模块文件的工作拷贝。
$cvs checkout CVSROOT/modules
$cd CVSROOT
2.
编辑这个文件并写入定义模块的行。请参见2.4节[管理文件的介绍]。有一个简单介绍,参见C.1节
[模块文件]。有它的详细描述。你可以使用下面的行定义模块"tc":
tc yoyodyne/tc
3. 提交你的更改到仓库
$cvs commit -m "Added tc module." modules
4. 发行模块文件
$cd
$cvs release -d CVSROOT
4
=======
5 分支与合并
==================
CVS允许你独立出一个派生的代码到一个分离的开发版本---分支。当你改变一个分支中的文
件时,这些更改不会出现在主开发版本和其它分支版本中。
在这之后你可以使用合并(merging)把这些变更从一个分支移动到另一个分支(或主开发版
本)。合并涉及到使用“cvs update -j”命令,合并这些变更到一个工作目录。你可以确认
(commit)这次版本,并且因此影响到拷贝这些变更到其它的分支。
-----------------------------------------------------------------------------------
5.1 何时应当创建一个分支
假定tc.c发行版已完成。你正在继续开发tc.c,计划在2个月后发行1.1的版本。在不久以后你的
客户开始抱怨说代码有些问题,你检查了一下1.0的发行版(请参见4.4节[标笺])并且找到了这
个错误(这将会有一个小小的更正)。但是,这个当前的版本是处于一个不稳的状态,并且在下
一个月才能有希望稳定下来。这样就没有办法去发行一个最新的现有版本去更正问题。
这时就可以去创建基于这棵版本树1.0版的分支。你可以修改这棵树的分支而不影响到主干。当
修订完成时,你可以选定是否要把它同主干合并或继续保留在这个分支里。
-----------------------------------------------------------------------------------
5.2 建立一个分支
你可以使用“tag -b”去建立一个分支。例如,假定你在工作于一个工作拷贝中:
$cvs tag -b rel_1_0_patches
这将基于当前的拷贝分离出一个分支,并分配“rel_1_0_patches”的名字。
懂得分支是在CVS仓库中创建,而非在工作拷贝中创建的是非常重要的。正上面的例
子,创建一个基于当前版本的分支不会自动把当前的工作拷贝转到新的分支上。欲知
详情,请看5.3节[进入 一个分支]。你也可以不参考任何工作拷贝而建立一个分支。
你可以使用rtag命令:
cvs rtag -b -r rel-1-0 rel-1-0-patches tc.
“-r rel-1-0”说明这个分支是基于标志了rel-1-0的版本文件,它不是从最新的版本
开始分支.这对需要从老的版本进行分支很有用(例如:当修订一个过去的稳定版本时)
当使用“tag”标志,这个“-b”标志告诉rtag去创建一个分支(而非是这个版本的符号
连接)。注意标记“rel-1-0”可能对不同的文件有不同的版本数字。因此,这个命令的结果
是为tc模块建立了一个命名为“rel-1-0-patches”的新版本分支,它是基于标记为“rel-1-0”
的版本树。
-----------------------------------------------------------------------------------
5.3 进入分支
你可以通过两种方式进入分支:重新checkout或是从现存的拷贝进入。重新checkout使用
checkout命令并带上“-r”标识,后面是这个分支的标笺(tag)名。(请看5.2[创建一个分支]):
$cvs checkout -r rel-1-0-patches tc.
或者如果你已有了一个拷贝,你可以使用“update -r”命令转到这个分支。
$cvs update -r rel-1-0-patches tc.
或者使用另一个等同的命令:
$cd tc
$cvs update -r rel-1-0-patches
这对现有拷贝为主干代码或是其它分支都是有效的.上面的命令将把它转到命
名的分支。同“update”命令相类似。“update -r”合并你所做的任何改变,请注
意是否有冲突出现。
一但你的工作拷贝已经转向一个特定的分支。它将一直保持在这个分支内,除非你
又做了其它的操作。这意味着从这个工作拷贝checkin的变更将加到这个分支的新版
本中,而不影响到主干版本和其它分支代码。
想看一个工作拷贝是基于哪一个分支,可以使用“status”命令。在它们输出中查找
一个“sticky tag”的域(请参见4.9节["sticky tag"],第38页).那就是你的当前分支号。
$cvs status -v driver.c backend.c
====================================================================
File: driver.c Status: Up-to-date
Version: 1.7 Sat Dec S 18:25:54 1992
RCS version: 1.7 /u/cvsroot/yoyodyne/tc/driver.c,v
Sticky Tag: rel-1-0-patches (branch: 1.7.2)
Sticky Date: (none)
Stick Option: (none)
Existing Tag:
rel-1-0-patches (branck: 1.7.2)
rel-1-0 (revision: 1.7)
====================================================================
File: backend.c status: Up-to-date
Version: 1.4 Tue Dec 1 14:39:01
Rcs Version: 1.4 /u/cvsroot/yoyodyne/tc/
Sticky Tag: rel-1-0patches(branch:1.4.2)
Sticky Date: (none)
Sticky Option: (none)
Existing Tag:
Rel-1-0-patches (branch: 1.4.2)
Rel-1-0 (revision: 1.4)
Rel-0-4 (revision: 1.4)
请不要因为每个文件的分支是不同(“1.7.2”和1.4.2")而迷惑。分支的标笺(tag)
是相同的:"rel-1-0-patches",这些相同标笺的文件是相同分支的。在以上的例子中,分支建
立之前,"driver.c" 比 "backend.c"有更多的变更,因此它们的版本编号是不同的。请参见5.4节
[分支和主干版本号]去了解分支如何构建原理的细节。
--------------------------------------------------------------------------------------
5.4 分支与主干版本
通常,一个文件的主干版本历史是一个增长线(请看4.1[主干版本]页):
+-----+   +-----+   +-----+   +-----+   +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
+-----+   +-----+   +-----+   +-----+   +-----+
然而,CVS并不局限于线性的开发。主干版本可以分为不同的分支,每一个分支可
以是一个独立的自我维护的开发线。而在一个分支中的变更可以很容易的转移到主干中。
每一个分支均有一个分支号,由一个“.”分离的十进制奇数组成,分支号的编排依
赖于它分离出的主线版本。使用分支号允许从一个特定版本分离出多个分支。
所有的分支版本都依赖于它的原始分离版本号。下面的例子将展示这一点。
                        +-------------+
        1.2.2.3.2 分支 ->       +--! 1.2.2.3.2.1 !
                        ! +-------------+
                        !
        +---------+   +---------+   +---------+
1.2.2 分支-> +--! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.2 !
        ! +---------+   +---------+   +---------+
        !
        !
+-----+   +-----+   +-----+   +-----+   +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- 主干
+-----+   +-----+   +-----+   +-----+   +-----+
        !
        !
        ! +---------+   +---------+   +---------+
1.2.4 分支-> +--! 1.2.4.1 !----! 1.2.4.2 !----! 1.2.4.2 !
        +---------+   +---------+   +---------+
你是如何创建具体的分支号的细节通常不是你需要考虑的,但这里谈谈它如何工作。
当CVS建立一个分支号时,它先得到第一个未用的偶数,开始的数字是2,例如你
从6.4的主干版本创建分支时,分支号为6.4.2所有分支号码末位为0的号码用于CVS内
部,(例如6.4.0)。(请参见5.5节[内部分支号]44页)分支1.1.1有特别的含义,请看13章
[跟踪代码]。
-----------------------------------------------------------------------------------
5.5 内部分支号码
这一节描述CVS的内部分支(magic branches) (* 译者注:magic branch 译为内部分支)
特性。在大多数情况下,你不用考虑内部分支号码,CVS将为你进行管理。然而,在
一些特定条件下,它将显现出来,因此理解它如何工作将是有用的。一般的,分支号
码将由奇数个 "."分隔的十进制整数组成。请看4.1节[版本号码]。然而那并非完全是这
样的,由于效率的原因,CVS有时插入一个额外的“0”在右末的第二个位置(1.2.4
变为1.2.0.4,8.9.10.11.12变为8.9.10.11.0.12等)。
CVS将会很好的将这些变换隐蔽在背后进行,但在一些地方,这种隐蔽并不完全:
* 内部分支编号会出现在CVS的日志(log)文件中。
* 你不能够对 "cvs admin" 使用符号分支名。
你可以使用admin命令去为一个分支重新分配一个RCS希望的那样的符号名。如果
R4patches是一个分配给分支1.4.2(内部分支编号为1.4.0.2)的一个文件"numbers.c"的
命名,你可以使用如下命令:
$cvs admin -NR4patches:1.4.2 numbers.c
它将只在至少一个版本已经提交到这个分支时才会有效。请非常小心不要把一个标
笺(tag)分配给了一个错误标识号(现在没有看到昨天的一个标笺是如何分配的)。
----------------------------------------------------------------------------------
5.6 合并一个整个分支
你可以合并一个分支到你的工作目录在“update”命令中“-j 分支号”的标识。使
用“-j 分支号”将合并这个派生分支点与原版本的最新版之间的变更到你的工作目录
“-j”的意思是“join”。
我们现在来考察下面这棵树:
+-----+   +-----+   +-----+   +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 ! <- 主干
+-----+   +-----+   +-----+   +-----+
        !
        !
        ! +---------+   +---------+
R1fix 分支-> +--! 1.2.2.1 !----! 1.2.2.2 !
        +---------+   +---------+
       
分支1.2.2分配了一个Rifix的名字.下面的例子假定模块"mod"只包含一个文件"m.c"
$cvs checkout mod             # 得到最新的1.4版
$cvs update -j R1fix m.c         # 合并所有在分支中的改变,即:1.2与1.2.2.2
                            # 之间的变化到这个文件的工作目
录.
$cvs commit -m "Included R1fix   # 建立1.5版
在合并时可能会发生冲突,如果这种情况发生,你可以在提交新版本之前解决它。请
参见10.3节[冲突的例子]。
如果你的原文件中包含关键字(请看第12章[关键字替代])。你可能会得到比严格意义
上的冲突更多的冲突信息。请参见5.10节[合并和关键字],去了解如何避免这个问题。
"checkout"命令也支持使用"-j"参数。下面的例子同上面所用的例子有相的效果。
$cvs checkout -j R1fix mod.
$cvs commit -m "Included R1fix"
---------------------------------------------------------------------------------
5.7 从一个分支多次合并。
继续我们上面的例子。现在这棵树看起来是这样的:
+-----+   +-----+   +-----+   +-----+   +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- 主干
+-----+   +-----+   +-----+   +-----+   +-----+
        !               *
        !             *
        ! +---------+   +---------+
R1fix 分支-> +--! 1.2.2.1 !----! 1.2.2.2 !
        +---------+   +---------+
正如上面所讨论的,分支1.2.2.2所引导的“*”号表示从Rifix分支到主干的合并。
现在我们继续开发Rifix分支:
+-----+   +-----+   +-----+   +-----+   +-----+
! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- 主干
+-----+   +-----+   +-----+   +-----+   +-----+
        !               *
        !             *
        ! +---------+   +---------+   +---------+
R1fix 分支-> +--! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
        +---------+   +---------+   +---------+
然后你可能会希望合并新的变更到主干中去。如果你仍使用“cvs update -j Fifix m.c"
cvs将试图合并你已经合并过的东西,这可能写导致一些不希望发生的东西。
因此,你必须表达清楚你希望只合并未被合并的内容的意思。这样需要使用两个
“-j“参数。CVS合并从第一个“-j”的版本到第二个“-j”版本的变化。例如,在我们上面
的例子中:
cvs update -j 1.2.2.2 -j R1fix m.c
如果出现的问题是你需要手工指定1.2.2.2的版本号,一个更好的方法是使用:
cvs update -j R1fix:yesterday -j R1fix m.c
然而,更好的方式是在每一次合并后重新放一个标笺给Rifix分支,然后使用标
笺做后的合并:
cvs update -j merged_from_Rifix_to_trunk -j R1fix m.c
----------------------------------------------------------------------------------
5.8 合并两个任意版本之间的不同
使用两个“-j”标志,这个update(和checkout)命令能合并两个任意不同的版本
到你的工作目录。
$cvs update -j 1.3 backend.c
将把1.5版本恢复到1.3版本,所以一定要注意版本的顺序。
如果你在操作多个文件时使用这个选择项,你必须了解在不同的文件之间,版本的
数字可能是完全不同的。你必须使用标笺(tag)而不是使用版本号来完成多个文件
的操作。使用两个“-j”操作也能会恢复增加或删除的文件。例如,假定你有一个
叫“file1”的文件在在于1.1版本中,然后你在1.2版本中删除了它,下面是如何操作的例子:
$cvs update -j 1.2 -j 1.1 file1
file1
$cvs commit -m test
checking in file1;
/tmp/cvs-sanity/cvsroot/first-dir/file1 file1,v
new revision:1.3; previous revision:1.2 done
$
------------------------------------------------------------------------------------
5.9 合并能添加和删除文件
如果你在合并时的改变涉及到添加或删除一些文件,“update -j”将反映这些变化。
例如:
cvs update -A
touch a b c
cvs add a b c ; cvs ci -m "added" a b c
cvs tag -b branchtag
cvs update -r branchtag
touch d ; cvs add d
rm a ; cvs rm a
cvs ci -m "added d , removed a"
cvs update -A
cvs update -j branchtag
在这些命令之后(注意要commit),文件'a'将被删除,而文件'd'将被加入到主干。
-------------------------------------------------------------------------------------
5.10 合并和关键词
如果你合并的文件包含关键词(参见第12章[关键词替代],73页),你通常将会在
合并时得到 无数个冲突报告,因为在不同版本中非常不同。
因此,你常需要在合并时使用“-kk”(参见12.4节[替代模式],75页)选择项。使用
关键字名字,而非去扩展关键字的值的方法,这个功能选择项确保你合并的版本之间互相相
同,而避免了冲突。
例如:假设你有一个文件如下:
        +---------+
  br1   -> +--! 1.1.2.1 !
        ! +---------+
        !
        !
+-----+   +-----+
! 1.1 !----! 1.2 !
+-----+   +-----+
并且你的当前工作目录拷贝为主干(1.2版本)。那么对于以下的合并将会产生一个
冲突的结果。请看例子:
$cat file1
Key $Revision: 1.3 $
...
$cvs update -j br1
U file1
RCS file: /cvsroot/first-dir/file1,v
retrieving revision 1.1
retrieving revision 1.1.2.1
Meging differences between 1.1 and 1.1.2.1 into file1
rscmerge: warning: conflicts during merge
$ cat file1
$<<<<<<< file1
Key $Revision: 1.3 $
=======
Key $Rerision: 1.1.2.1 $
$>>>>>>> 1.1.2.1
...
冲突发生在试图将1.1和1.1.2.1合并到你的工作目录中去的时候。因此,当这个
关键词从“Revision:1.1"到"Revision:1.1.2.1"时,CVS将试图合并这个变化到
你工作目录, 这就同你的目录中的变更“Revision:1.2"发生了冲突。
以下是使用了:“-kk”后的例子:
$cat file1
key $Revision: 1.3 $
...
$cvs update -kk -j br1
V file1
RCS file: /cvsroot/first-dir/file1,v
retrieving revision 1.1
retrieving revision 1.1.2.1
Merging differences between 1.1 and 1.1.2.1 into file1
$ cat file1
key $Revision: 1.3 $
...
在这里版本“1.1”和“1.1.2.1"都扩展为单纯的 "Revision",因此,合并时就不会
发生冲突了。
然而,使用 "-kk" 参数还一个主要的问题。即,它使用了CVS通常使用的关
键字扩展模式。在特殊情况下,如果模式使用针对二进制文件的 "-kb"
参数。这将会产生问题。因此,如果你的数据库中包括有二进制文件,你将
必须手工处理这些问题,而不能使用 "-kk"。
10 多个开发者同时工作
---------------------
当多个开发者同时参与一个项目时,常常会发生冲突。一般经常发生的情况是两个人想
同时编辑一个文件的时候。它的解决方法之一是文件锁定或是使用保留式的checkout,这种
方法允许一个文件一次只允许一个人编辑。这是一些版本控制系统的唯一解决方式,包括
RCS和SCCS。现在在CVS通常使用保留式checkout的方法是使用"CVS admin-1"命令(参见A-6-1AB
[admin选择项])。在下面将解释这不是一种好的智能的解决方式,当它是许多人喜欢使用的
一种方式。下面也将讲述可以使用适当的方法来避免两个人同时编辑一个文件,而非使用软件
的方式强迫达到这一点。
在CVS中默认的方法是"unreserved checkout"--非保留式的导出。在这种方法下,开发者
可以同时在他们的工作拷贝中编辑一个文件。第一个提交工作的没有一种自动的方法可以知道
另一个人在编辑文件。另一个人可能会在试图提交时得到一个错误信息。他们必须使用CVS命令
使他们的工作拷贝同仓库的内容保持更新。这个操作是自动的。
CVS可以支持facilitate多种不同的通信机制,而不会强迫去遵守某种规则,如"resered
checkouts"那样。以下的部分描述这些不同的方式是如何工作的,和选择多种方式之间涉及到
的一些问题。
10.1 文件状态
基于你对导出的文件使用过的操作,和这些文件在仓库中的版本使用过的操作,我们可以
把一个文件分为几个状态。这个状态可以由"status"命令得到,它们是:
up-to-date:
对于正在使用的这个分支,文件同仓库中的最后版本保持一致。
Locally Modified:
你修改过文件,但没有"commit"。
Locally added:
使用了"add"命令增加文件,但没有"commit"
Locally Removed:
你使用了"remove"命令,但没有"commit"
Needs checkout:
其他人提交了一个更新的版本。这个状态的名字有些误导,你应当使用"update"而非
"checkout"来更新新的版本。
Needs Patch:
象"Needs checkout"一样,但CVS服务将只给出Patch(补丁)文件,而非整个文件。而
给出Patch和给出整个文件的效果是相同的。
Needs Merge:
一些人提交了一个更新版本,而你却修改过这些文件。
File had conflicts on merge:
这同"Locally Modified"相象,只是"update"命令给出了一个冲突信息。如果你还没有
解决冲突,那么你需要解这个问题,解决冲突的方法参见10.3节[冲突的例子].
Unkown:
CVS不知道关于这个文件的情况.例如,你创建了一个新文件,而没有使用"add"命令
为了帮助弄清楚文件的状态,"status"也报告工作版本(working
vevision),这是这个文件是从哪个版本来的,另外还报告"仓库版本"(Repository
vevision)。这是这个文件在仓库中的这个版本分支的最后版本。
"status"命令的选择项例在附录B[invoking cvs]。有关"sticky tag"和"sticky
date"输出内容的信息,参见4.9节[sticky tags]。有关"sticky options"输出内容参见"-k"选择项,
A.16.1节[update选择项]。
你应当把"update"和"status"命令放在一起来认识。你使用"update"使你的文件更新到最
新状态,你使用"status"命令来得到"update"命令将会做何种操作。(当然,仓库中的状态将可
能会在你运行update之前变化)。事实上,如果你想使用一个命令得到比使用"status"正式的状
态信息,你可以使用:
$cvs -n -q -update
这里"-n"选择项表示不真正执行update,而只显示状态;"-q"选择项表示不打印每个目录的
名字。有关更多的关于"update"命令的住处参见附录B[使用CVS]。
10.2 使一个文件更新到最版本
当你想更新或是合并一个,使用update命令。对于一个不是最新版本的文件,这个命令大略等
同于"checkout"命令:最新版本从仓库中提出并放到工作目录中。
当你使用"update"命令时,你修改过的文件在任何情况下不会受到损害。如果在仓库中没有更
新的版本,"update"时你的代码没有任何影响。当你编辑过一个文件,并且仓库中有更新版本,那
么"update"将合并所有的变更到你的工作目录。
例如,想象一个你导出了一个1.4版的文件并且开始编辑它,在某一时候其他人提交了1.5版,然
后又提交了1.6版,如果你运行update命令,CVS将把1.4版到1.6版之间的变更放到你的文件中。
如果在1.4版和1.6版之间的改变太靠近于的你一些变更的话,那么一个"覆盖"("overlop")冲突
就发生了。在这种情况下将输出一个警告信息,然后结果保留的文件中包含了有冲突代码的两个版
本,由特别的符号所分隔开。请参见A.16节[更新],可以得到关于"update"命令的一个完全的描述。
--------------------------------------------------------------------------------
Copyright 1999,China Linux Forum
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 1楼 发表于: 2005-07-30
如何利用PVCS进行项目文档管理
[文章信息]
作者:
时间: 2003-11-08
出处: 朗川软件
责任编辑: 方舟
[文章导读]
PVCS VM(版本管理)是软件配置管理工具PVCS 家族中的一个组成部分.
为什么选择PVCS VM? 在软件系统的开发过程中,开发人员经常会遇到这样的问题:
  1. 源代码和文档数量的急剧增加;
  2. 经常需要与错综复杂的多用户、多产品的软件版本打交道;
  3. 开发小组成员间源代码的更新和保存记录变得越来越复杂;
  4. 产品的多版本导致磁盘空间占有量浩大。
  实际上,上述问题可以归结为一个问题,即开发文档的版本控制问题:开发人员追踪、 记录整个开发过程而保?许多不同版本的程序源代码。从而可以有效地控制产品的设计质量,提高项目开发管理水平。
  PVCS VM(版本管理)是软件配置管理工具PVCS 家族中的一个组成部分。软件配置管理可以使软件开发队伍中的任何成员以一致,可重复的方式随时找回和创建应用的任何版本。
  VM详细记录了一个软件系统的所有变更,包括谁做了修改,什么时候,和为什么修改。通过VM,你可以轻易地找回任何先前的修订版本,并且确信这些文件不是被忽略重写的。当你检出一个文件时,VM将阻止其他用户对该文件的修改。
  通过VM,开发小组成员可以......
  * 建立配置文件,能够为所有用户提供一套相同的特征,或者为不同项目提供不同的特征。
  * 使用VM 特权设置每个用户的访问级别,以防止对文件和版本管理命令的未认证访问。
  * 重建任何文件的任何修订。可以快速而容易地回到任一工作文件的先前修订。
  * 用版本锁定来阻止其他用户对文件的修改,以及防止当文件更新时所造成的损失。
  * 软件开发中的并行线称为分支。VM可以追踪分支并且保持开发的独立进行,这样你就可以在不影响主线的情况下跟随开发的另一线。
  下面我们将应用PVCS VM(版本控制)工具来说明在软件项目中的“源码控制过程”。通过工程" Dynaweb"这个案例,来展示我们已经使用的过程模型,该源码控制系统的目的是:
  * 支持团队工作环境:在某个时刻,相同的文件会被2个以上的开发人员同时作修改。当他们做完修改后存盘,错误将会发生。后者覆盖了前者所做的修改,从而造成一些错误产生。而PVCS VM将控制源码的访问,从而避免超过1人以上用户修改相同文件的问题。
  * 保持发布版本变更的历史记录:通常,在产品发布以后,开发人员还需要继续修改源码。当QA报告发布版本的Bug信息时,开发人员所修改的源码与发布版本最初的源码不同。即使我们确实保?了原始发布版本的源码,在QA期间,开发人员要想在最新的版本上进行BUG的修改,这也是非常困难的。而我们使用PVCS VM保存源码变更的历史记录,那么我们就可以获得任意发布版本的源码。
  * 标准发布过程:通常开发人员是在自己的PC机上生成发布程序。这样做会导致一些错误发生,例如使用了错误源码进行发布,应用不同的设置来创建代码,等等。PVCS VM可以帮助我们集中管理发布构建的过程,以避免错误发生。
  在我们开始为源码控制而建立PVCS VM系统之前,我们需要先做一些准备工作:
  * 我们需要配置网络环境与服务器连接,还有工作站和开发人员的PC机。网络类型应该支持开发平台和PVCS VM系统。
  * 服务器通常是由公司网络部门提供的,需要有足够大的磁盘空间用于源码的存储,并且服务器上已经安装好PVCS VM系统。请参看《PVCS VM用户指南》的服务器安装。
  * 开发小组需要准备一个工作站(PC),在上面建立开发环境,这个环境与开发人员的相同,该工作站用于产品发布。开发环境包括一些构建工具,如编译器、链接器、创建文件等等,并且在工作目录下保存工作源文件。
  * 对于应用PVCS VM系统, 网络部人员和至少1名开发人员需要较好受过管理员这方面的培训。每个开发人员都应该知道如何应用PVCS VM进行开发源码的检入和检出操 作。
  PVCS VM是一个多用户的客户服务器网络工作环境。客户端是开发人员的工作站,服务器是公司网络部门文件服务器中的一个。
  * PVCS VM服务器是公司网络部文件服务器中的一个,由公司网络部门来维护。这个服务器保存着Dynaweb工程源码的所有主要数据和PVCS VM系统。它包含有两个主要的目录文件夹:
  * PVCS VM目录:该目录是由安装的PVCS VM服务器版本自动生成的。目录中包含PVCS VM服务器版本的所有工作文件和数据库。
  * 存档文件目录:该目录下保存着PVCS VM服务器中的所有工程源码档案。
  * 工作站包括所有开发人员的PC机和一台作为发布使用的配有标准编译环境的PC机。每一个工作站下都有三个主要的目录文件夹:
  * 工作文件目录: 该目录是本地PC机上的一个物理目录。它用于保存从服务器中检出的源码。开发人员使用这个目录下的文件进行开发工作,同时也从该目录下向服务器中检入文件。
  * 存档文件目录:该目录的物理位置是在PVCS VM服务器上,并作为一个逻辑目录被映射到每个本地工作站中。这个目录保存着所有工程的源码档案。
  * PVCS安装目录:该目录是在本地工作站安装PVCS VM时建立的。它保存着本地工作站中用于运行PVCS VM的文件。
  Dynaweb软件项目中的角色分配
  为了实现源码控制系统,对Dynaweb项目来说,我们需要分配多种角色来担任PVCS VM中的不同工作。这些角色具有不同的访问权限和负责不同的职责来贯彻整个项目的进行。这里,我们定义4种角色:
  * 网管
  * 项目经理
  * 系统操作人员
  * 开发人员
  这4种角色分别担负着PVCS VM权限定义中不同的权责,从项目请求启动->项目准备->源码的检入/检出->项目关闭—>数据备份等一系列操作中,各尽其职,如下面要说明的,遵循着源码控制行为。
项目开发中的源码控制行为
  在整个开发过程中,源码控制行为就是一条主线,指导着开发过程进行。
  1. 主动请求
  当项目Dynaweb过程模型的设计阶段完成以后,开发小组将进入项目开发的执行阶段和开始编码。
当程序代码生成,这些原始资源就需要应用源码控制系统来管理。在这个时候,项目经理就要请求?动源码控制系统。
  2. 构建和初始化
  在网管接受项目经理的请求并完成PVCS VM服务器磁盘空间预?工作后,开发小组开始在服务器上构建PVCS文件夹结构和检入所有原始文件进行初始化。这项工作是由系统操作人员来完成的。这个过程包括:PVCS VM的安装、创建项目文件夹、配置项目?性和工作路径、对所有工作文件的初始化等。
  3. 源码更新
  源码更新是开发人员的日常工作。其中包含两部分主要任务:源码的检入和检出。
  我们应用这个源码控制系统,对任何源码的更新过程,开发人员都必需遵循下面所列出的步骤:
  * 先要检出源码:开发人员需要从PVCS VM服务器上向本地工作目录中检出要进行修改的原始文件。
  * 修改本地的工作源文件:开发人员在本地工作目录中修改原始文件并在本机上测试。
  * 为更新数据检入修改的源文件:使用“check in”命令将修改的源文件从本地工作目录更新到PVCS VM服务器中。
  4. 发布
  在每一个里程碑,开发小组都需要向QA或OEM客户发布程序。项目经理将决定是否要产生发布,以及发布版本。发布的操作是由系统操作人员来完成的。系统操作人员首先检出所有源文件到工作空间中,然后在标准的发布环境中创建所有模型。
  5. 存档操作
  在通常的操作过程中,开发小组只是使用检入、检出和发布操作。存档结构并没有改变(仅仅是添加了修订和版本标签)。但是,有时设计被改变,源文件增加或减少了,存档结构也随着改变。由于设计的改变会影响到整个项目的变动,因此需要由项目经理来确认。存档结构的任何改变都需要项目经理检验并由系统操作人员来完成改变。这个改变的操作包括添加或删除存档文件夹,添加或删除存档文件,生成一个新的分支,等等。
  6. 请求关闭
  在项目关闭之后,便于项目关闭里程碑今后的使用,源代码档案需要在其它媒介(如MD, 或CD)上做一次备份。如果这些源码不需要改变,那么要将源代码档案从PVCS服务器中删除。如果项目进入维护阶段,源码将保存在服务器中供维护使用。项目经理首先需要请求关闭项目,然后由网管进行备份,并基于请求删除或保?服务器中的源代码档案。
  7. 备份
  在源码控制周期中,网管将根据《公司服务器维护指南方针》维护PVCS VM文档服务器。这项工作包括对服务器中的源码档案做备份,是由网管人员来完成的。
  在执行上面的源码控制行为中,开发小组中不同角色的人员需要根据“批准流程”提交请求表:
  * PVCS项目请求
  在项目进行中,我们可能遇到核心端口问题。这些情况需要修改深层存档的项目结构(如删除文件夹,添加文件,删除文件或文件移动,等等)研发人员需要请求并遵从“批准流程”来填写PVCS项目请求表,然后请求才被执行。这样做的好处是可以保护存档的完整性,可以使每个研发人员知道这次所做的修订,并且在项目生命周期中保存存档记录。
  * 项目发布请求
  对于项目发布请求,请求者需要填写项目发布请求表,然后发布才被执行。
  这样做的好处是可以在每次修订(由某人、某时、某种目的所做的修订)发布中保?完整的记录。项目经理可以追踪每次修订发布的错误和保持质量控制。
  通过PVCS VM进行的版本控制,可以帮助项目小组在整个开发周期内保持开发文档的变更,通过项目存档来跟踪变化,同时可以管理多种存档的修订版。从而使开发过程更加有组织、协同地进行。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
快速回复
限100 字节
 
上一个 下一个