Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1087062
  • 博文数量: 282
  • 博客积分: 10865
  • 博客等级: 上将
  • 技术积分: 2480
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-12 12:35
文章存档

2017年(1)

2016年(3)

2015年(10)

2014年(12)

2013年(5)

2012年(10)

2011年(29)

2010年(3)

2008年(13)

2007年(92)

2006年(104)

我的朋友

分类: Java

2006-11-14 12:11:31

在具有版本管理的小组开发环境中,有些操作是开发人员几乎每天都要进行的,如提交修改工作、更新本地工作拷贝、解决冲突等。下面将详细介绍在ECLIPSE中如何实现这些日常操作。在进行这些操作前,都需要先建立与CVS服务器的连接。在ECLIPSE中进行这些操作时,如果是对目录进行操作,则ECLIPSE会自动对该目录下的子目录和文件进行相同的操作,对目录的操作是递归嵌套的。本文在下面的讲解中只以文件操作为例,但这些操作也适用于目录。一般来说,如果在某个目录下要对多个文件进行相同的操作,则选择目录操作比较简便。另外,如不特别说明,CVS资源库中的文件指的是属于主分支HEAD的文件。

下面分四种不同的工作场景介绍如何将对工作拷贝的修改反映到CVS资源库。

a.签出模块后,在本地(Local)对文件进行了修改,CVS资源库中的文件没有变化。

在工作拷贝中对SimpleTest.java作一些改动并保存,此时ECLIPSE的画面见图17。在改动的文件及其所属的目录前都出现一个箭头,在希望提交的文件上点击右键,在出现的弹出菜单中选择【Team】→【Commit...】,在随后出现的对话框中输入注释后单击OK按钮。虽然注释不是必须输入的,但是,最好养成在每次提交时写注释的良好习惯,这在实际的系统开发过程中是很有必要的。提交成功后文件的修订版本号会自动增加,如图18所示,SimpleTest.java的修订版号从1.1变成了1.2。



图17:在ECLIPSE中能明确地标识被修改过的工作拷贝


图18:提交修改后,修订版号自动增加

b.签出模块后,在项目中新建了新文件,希望将新建的文件追加到CVS资源库中。

在新建的文件上点击右键,在出现的弹出菜单中选择【Team】→【Add to Version Control】。需要注意的是:上述操作并没有把新建的文件追加到CVS资源库中,为了把新建的文件追加到CVS资源库中,还要执行下列操作:在新建的文件上点击右键,在出现的弹出菜单中选择【Team】→【Commit...】。

c.签出模块后,在项目中删除了文件,希望在CVS资源库中也删除相应的文件。

首先在项目中删除文件,然后在被删除文件的父目录上点击右键,在出现的弹出菜单中选择【Team】→【Commit...】。值得指出的是:上述操作只是将被删除的文件从主分支上删除了,但并没有从CVS资源库中被完全删除,也不应该从CVS资源库中被完全删除,因为某个标签或分支可能需要被删除的文件。

如果想恢复被删除的文件,在ECLIPSE的Navigator视图中选中被删除的文件的父目录,在右键菜单中选择【Team】→【Restore from Repository...】,然后在出现的对话框中选择希望从哪个修订版恢复被删除文件的内容。

d.签出模块后,在本地(Local)对文件进行了修改,但在提交之前,其他的开发人员已经对同一个文件进行了修改并提交到CVS资源库中。

此时,由于CVS资源库中该文件的修订版本号将高于本地该文件的修订版本号,因此将不能提交该文件。如果试图提交该文件,ECLIPSE将弹出一个错误对话框,见图19。在这种情况下,为了能提交修改必须首先解决冲突。详细操作见下文的冲突解决。



图19:在冲突状态下提交将出现错误

在小组开发环境中,应该经常性地提交自己的工作成果,但也不能随意提交。一般来说,以提交的更改不对其他开发人员造成妨碍为前提条件。例如,提交的代码应能够被正常编译。如果在小组开发环境中还使用了诸如CHECKSTYLE之类的代码审查工具,则提交的代码除了能够被正常编译之外,还应能通过代码审查工具的审查。

在系统的开发过程中,开发人员不应只关注自己的开发,还应尽量与其他开发人员保持同步,也就是需要经常地将其他开发人员的开发成果更新到本地的工作拷贝中。

a. CVS资源库中的文件被更新了,但本地文件没有更新。

在开发小组中,可能有部分开发人员负责一些通用模块的开发,而其余的开发人员则专注于业务系统的开发。在这样的开发场景中,业务系统的开发人员就应经常更新通用模块,保持工作拷贝中的通用模块与CVS资源库中通用模块的同步。在文件上点击右键,在出现的弹出菜单中选择【Team】→【Update...】。本地文件的内容将被替换为CVS资源库中相应文件的内容。

b. CVS资源库中的文件没有被更新,但本地文件被更新了。

此时,由于本地文件的修订版号与CVS资源库中文件的修订版号相同,更新操作实际上什么也不做。

c. CVS资源库中的文件和本地文件都被更新了。

此时,ECLIPSE会尽量将CVS资源库中的内容合并到本地文件中。如果在合并过程中没有发现冲突,则合并后的文件将包含本地修改和其他开发人员的修改;如果在合并过程中产生了冲突,则ECLIPSE会在合并文件中着重显示相冲突的部分,并将原本地文件作一个备份。图20~23演示了这一过程。cvstest.txt文件1.2版本的三行的内容分别为test line1、test line2、test line3。用户jiangch将文件内容修改并保存后的结构如图20,在jiangch提交之前,用户cvsuser2已将文件内容修改并提交,此时CVS资源库中cvstest.txt的修订版号为1.3,见图21。



图20:存在冲突的更新1--用户jiangch的修改结果


图21:存在冲突的更新2--用户cvsuser2修改并提交后的结果

用户jiangch在文件cvstest.txt上进行更新操作后的结果见图22。



图22:存在冲突的更新3--用户jiangch进行更新操作后的结果

第二行保持不变,但产生冲突的第一、三行则被标记出来了。cvstest.txt的修订版号也变为1.3并处于已修改状态,新产生的文件.#cvstest.txt.1.2是修订版号1.2的备份文件。通过手工将jiangch与cvsuser2的修改内容合并后就可以进行提交操作了,图23是一个合并后提交的结果。



图23:存在冲突的更新4--用户jiangch合并后提交

ECLIPSE为CVS的操作提供了一个非常实用的功能:同步透视图(Team Synchronizing Perspective)。通过同步透视图,我们可以在提交、更新操作之前就发现可能存在的冲突。使用ECLIPSE小组开发环境的开发人员都应该熟悉同步透视图的使用。图21~24演示了如何使用同步透视图。在cvstest.txt 1.6与cvstest2.txt1.13的基础上用户jiangch对这两个文件进行了修改并保存。此时的结果如图24。



图24:冲突解决1--用户jiangch的修改结果

用户cvsuser2也在cvstest.txt 1.6、cvstest2.txt 1.13、TextRunnerTest.java1.1的基础上对这三个文件进行了修改并将修改结果提交到了CVS资源库。其结果见图25。



图25:冲突解决2--用户cvsuser2修改并提交后的结果

如果用户jiangch不能确定只有他一个人会修改这两个文件,他可以在如图21的画面上选择这两个文件并点击右键,在出现的弹出菜单中选择【Team】→【Synchronize with Repository...】,出现如图26所示的画面。图中①②③④所标识的按钮是过滤器,分别对应4种模式,可以控制在同步视图中显示何种状态的文件。

①:Incoming模式,显示CVS资源库中修订版号高于工作拷贝的文件。在实际工作中,可以选中此类文件并在右键菜单中选择【Update】。也就是将其它开发人员的开 发成果反映到自己的工作拷贝中,保持与其它开发人员的同步。

②:Outgoing模式,显示工作拷贝作了修改的文件。在实际工作中,可以选中此类文件并在右键菜单中选择【Commit】。也就是将自己的开发成果反映到CVS资源库。

③:双向模式,显示所有不同步的文件。包含模式①、模式②、模式④。

④:冲突模式,只显示在本地拷贝与CVS资源库都修改过且产生了冲突的文件。模式①-模式③包含了冲突模式。



图26:冲突解决3--同步透视图

处于冲突状态下的文件是不能提交的,为了提交产生冲突的文件,首先必须解决冲突。双击产生了冲突的文件,可以在一个特殊的对比编辑器中同时显示本地的工作拷贝文件与CVS资源库中的文件。通过这个编辑器可以方便地看到哪些地方存在冲突并解决冲突。例如在图26中,假定希望将工作拷贝的第一行和CVS资源库的第三行作为最终的修改结果,可以从编辑器的第二列拷贝第三行到第一列的第三行并保存。在同步视图中提交修改的操作:

1.在希望提交的文件上点击右键,在出现的弹出菜单中选择【Team】→【Mark As Merged】,这将使文件从冲突模式变为Outgoing模式。

2.在文件的右键菜单中选择【Team】→【Commit】。图27是提交后的结果画面。同步透视图还包含了很多其它的实用功能,关于同步透视图中各种按钮与右键菜单的说明可以查阅ECLIPSE的联机帮助文档。



图27:冲突解决4--用户jiangch合并后提交

在软件项目的开发进程中,可能需要参考历史版本的信息,甚至将某个文件的内容回复到某个历史修订版。在ECLIPSE中也提供了这方面的功能。文件或目录的右键菜单【Compare With】提供了和其它修订版相比较的功能;右键菜单【Replace With】提供了将工作拷贝的内容替换为其它修订版内容的功能。例如,我们修改了工作拷贝的某个文件后又想放弃修改内容,此时,可以选中文件并在右键菜单中选择【Replace With】→【Last from Head】(假定CVS资源库没有被其他人员更新过,否则【Replace With】→【Revision...】)。上述操作对目录而言,实际上是对该目录中的所有文件执行操作。

在ECLIPSE中,通过文件的右键菜单【Team】→【Show Resource History】可以方便地查询文件的修改履历,例如文件cvstest.txt在某个时刻查询到的修改履历见图28。从中可以看出谁在什么时候修改了文件的内容,也可以看出在每次提交时都写注释会有助于追踪代码的修改意图及今后的代码维护工作。



图28:文件修改履历




回页首


考虑下面的应用场景:在项目基本完成的时候,我们希望为此时的文件状态(快照)建立一个标签milestone1。在后续的程序修改过程中,如果发现了一些在版本milestone1中不存在的BUG,我们就可以用milestone1这一统一的标识获取当时的文件快照并与修改后的文件进行对比,而不需要对每个文件都记住其修订版号。

在ECLIPSE中,有两种方法给模块建立标签。方法1.在工作拷贝上建立标签,就JAVA项目而言,可以通过JAVA透视图的右键菜单进行操作;方法2. 在CVS资源库视图中建立标签。在建立标签之前,最好保持工作拷贝与资源库的同步。以方法2为例,在CVS资源库视图的HEAD节点下选中希望建立标签的模块,在出现的右键菜单中选择【Tag as Version...】,在随后出现的对话框中添加标签名即可。图29是对模块UnitTest建立了milestone1和milestone2两个标签后的结果。



图29:建立了两个标签后的CVS资源库视图

标签与文件修订版号的关系见图30。某个标签内各个文件的修订版号可能不同,例如在标签1中,文件A的修订版号是1.2,而文件B的修订版号是1.3;同一个文件的相同修订版号也可能分属于不同的标签,例如在标签1和标签2中,文件B的修订版号都是1.3。



图30:标签示意图

从标签签出的模块是静态的,即使修改了本地的拷贝文件也不能向资源库提交。为了证实这一点,读者可以先签出Versions节点下的模块,在本地做修改后再向CVS资源库提交修改。此时将出现类似图31的错误提示画面。表明提交的文件属于标签milestone1,而milestone1不是分支因而不能提交。



图31:从标签签出的拷贝修改后也不能被提交

6.2.1 建立分支

虽然通过标签可以方便地管理多个文件的修订版号,但是通过标签获得的文件拷贝是静态的,无法在其基础上修改并提交。因此,也就不能支持下面场景中的并发开发。假设某软件公司经过一段时间的开发,发布了产品A的1.0版。为了进一步扩大该产品的市场份额,随即在1.0版本的基础上进一步研发功能更强大的2.0版。但是公司还必须对产品1.0版进行维护和支持,如果用户在1.0版的使用过程中发现了BUG,应能尽快推出1.0修正版并发布相应的补丁程序。也就是说,开发人员要能在1.0修正版与2.0版这两条开发路线上同时工作。建立分支则可以支持上述要求。

与建立标签类似,在ECLIPSE中建立分支也有两种方法。本文以在CVS资源库视图中的操作为例演示分支的建立过程,其步骤如下:

1. 按建立标签的方法建立一个新的标签,例如v1_0。

2. 选中新标签v1_0,在右键菜单中选择【Add to Branch List...】(不限于新标签v1_0,可以在任意标签上操作,但是建立分支应当在关键时刻进行)。

3. 在出现的对话框中输入分支名,例如输入"UnitText1_0_X"并确定,此时就建立了分支。但是,此时的分支是空的,没有与之相关联的资源。

4. 选中新标签v1_0,在右键菜单中选择【Tag with Existing...】,在出现的对话框中打开节点Branches并选择在步骤3新建立的分支UnitText1_0_X,最后按OK按钮确定后就完全建立了一个新的分支,分支建好后的CVS资源库视图如图32所示。



图32:建立分支后的CVS资源库视图

现在,就可以从主分支和UnitText1_0_X分支分别获得工作拷贝。从主分支获得的工作拷贝在提交后将反映到主分支上,而从UnitText1_0_X分支上获得的工作拷贝在提交后将反映到UnitText1_0_X分支中,在主分支和UnitText1_0_X分支上可以互不影响地进行并发开发。结合上述开发场景,产品A 1.0版的修正版对应UnitTest1_0_X分支,而产品A 2.0版可以在主分支上继续开发。

6. 2.2 分支修订版号

分支中的修订版号与主分支中的修订版号略有不同,主分支、分支及修订版号的关系可用图33来说明。



图33:主分支与分支示意图

图34显示了文件cvstest.txt在UnitTest1_0_X分支上第一次提交后修订版号的变化情况。其修订版号不是从"1.10"转变为"1.11",而是转变为"1.10.2.1"。如果对该文件再进行一次提交,其修订版号将转变为"1.10.2.2"。即变化的是最后一个小数点后的数字。



图34:分支修订版号变化

6.2.3 将分支上的修改合并到主分支

继续2.1中的场景,开发人员在开发产品A 2.0版的同时还对1.0版进行维护。开发人员根据产品A 1.0版用户的反馈修正了一些BUG,由于产品A 2.0版也是基于1.0版继续开发的,他们发现有些BUG在开发中的2.0版中也存在。此时,就希望能将1.0修正版中的修改合并到主分支中。

图35-39演示了分支合并的过程。建立UnitTest1_0_X分支后继续在主分支上修改并提交cvstest.txt,结果如图35所示。



图35:分支合并1--主分支中的文件内容

从UnitTest1_0_X分支签出一个项目(如果用户jiangch或cvsuser2使用现有的ECLIPSE,则在签出项目时需要选择【Check Out As...】菜单并给项目取一个不同于"UnitTest"的名字),对文件cvstest.txt进行修改并提交,结果如图36所示。从图36还可以看出,从分支签出的项目在项目名称的后面还会注明分支的名称。



图36:分支合并2--UnitTest1_0_X分支中的文件内容

选择主分支工作拷贝的cvstest.txt,在其右键菜单中选择【Team】→【Merge...】,出现如图37所示的对话框。在"希望被合并的分支或标签"输入框中输入"UnitTest1_0_X";在随后的"通用基版本" 输入框中输入"v1_0",其意义为分支的起源版本(参见本文建立分支的步骤3和步骤4)。



图37:分支合并3--选择希望被合并的分支及其起始标签

在图37中点击"Finish"按钮,将出现同步透视图。如果希望将分支中文件内容的第二行合并到主分支中,只需将其从对比编辑器第二列拷贝至第一列,然后在文件的右键菜单中选择【Mark as Merged】(见图38),最后在文件的右键菜单中选择【Commit】。



图38:分支合并4--在透视图中进行合并操作

合并后的结果见图39。



图39:分支合并5--合并后主分支的结果




回页首


本文通过实例讲述了如何在ECLIPSE中使用CVS进行版本管理,由于ECLIPSE内置了丰富的CVS功能,本文的内容不可能面面俱到,例如,本文没有涉及在ECLIPSE中修改CVS的相关设置。想进一步了解相关内容的读者可以参考联机帮助文档及文后的参考资料。另外,限于水平,文中如有不当之处,敬请批评指正。

阅读(2595) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~