深入理解CVS版本控制:从项目添加到代码合并
1. 查看可用项目
在操作之前,我们可以展开Head主干以查看其中可用的项目。到目前为止,通常只有一个项目——CVSROOT,这是因为默认情况下,它是
C:/cvsroot
下的一个目录。进一步展开CVSROOT,就能看到该项目下的可用文件。
2. 向CVS添加项目
虽然CVSROOT很有趣,但我们应该添加自己的项目,比如ShelterSite到CVS中,并将其作为开发过程的一部分。这里需要注意,CVSROOT(全大写)是项目的CVS元数据目录,而cvsroot(全小写)是CVS的根目录,所有源文件都存储在此。
添加项目的具体步骤如下:
1. 在cvsroot下为项目创建一个目录。这将在Eclipse连接时将我们的应用程序注册为一个项目。目录名称可以随意命名,但为了简单起见,最好与Eclipse中的项目名称相关,甚至完全相同。
2. 返回PHP透视图或资源透视图。在导航器视图中,右键单击项目名称ShelterSite,选择“Team | Share Project…”,进入共享项目向导的第一部分。这里的“Team”菜单项是Eclipse存放所有CVS命令的地方,后续会经常用到。
3. 从可用选项中选择CVS,然后点击“Next”按钮。如果安装了其他版本控制系统插件,如PHPEclipse附带的Subversion插件,这里也会显示出来。
4. 选择要使用的存储库。该列表会从CVS存储库视图中的存储库列表中填充。可以选择其中一个可用的存储库,也可以选择“Create a new repository location”进入添加存储库向导。
5. 选择我们已经设置好的存储库,点击“Next”继续。
6. 选择要在CVS中存储应用程序的名称。如果CVS项目目录的名称与Eclipse项目名称相同,可以选择第一个选项;如果目录名称不同,可以选择“Use specified module name”并指定现有目录。若要浏览CVS中的可用项目,可选择“Use an existing module”,此时会显示cvsroot下的可用目录列表。
7. Eclipse会询问是否要将其提交到Head主干或分支。由于目前这是源代码的唯一副本,它将作为主副本,所以选择合并到Head。
8. 点击“Next”对源代码进行最终预览。
9. 在最终确认屏幕上,可以查看即将提交的文件。点击“Finish”按钮,确认在CVS中创建项目。
10. 最后会出现一个屏幕,用于添加注释并验证提交。虽然Eclipse不要求提交时必须添加注释,但添加描述性的注释是一个很好的做法,这里我们简单注明这是初始版本。再次点击“Finish”按钮,提交将开始。
在导航器视图中,项目名称旁边会显示服务器名称,表明该项目已与CVS服务器关联。如果需要断开本地副本与CVS服务器的关联,例如在存储库服务器更改的情况下,可以右键单击项目,选择“Team | Disconnect…”。需要注意的是,“Disconnect”这个标签有点误导人,实际上如果项目与存储库关联,Eclipse并不会与服务器保持持续连接,只是记住与CVS服务器的关联。
每个源文件旁边的数字是版本号,标签会注明文件是ASCII文本文件还是二进制文件。版本号是CVS用于跟踪文件在特定时间点的标识号,每次提交时版本号会自动递增,仅保存文件更改时版本号保持不变。
3. 提交和更新
当我们对项目中的文件进行更改时,例如切换回PHP透视图,打开
ViewCats.php
页面,在页面底部添加一个指向网站管理员的链接:
</table>
Any questions? <a href="webmaster@sheltersite.org">email the webmaster!</a>
</body>
</html>
保存文件后,在导航器视图中,文件名前会出现一个右括号(>),这就是所谓的“脏标记”,表示该文件自上次更新后已被更改,需要提交。被修改的文件称为“脏”文件,而CVS中的文件称为“干净”文件。
提交文件的步骤如下:
1. 在导航器视图中右键单击该文件,选择“Team | Commit…”。
2. 系统会提示输入关于该文件的注释。输入注释后点击“Finish”按钮,文件将提交回存储库。
提交后,导航器视图中的脏标记会消失,文件名旁边会显示一个新的、更高的版本号。每次提交时,版本号都会递增。
在多人共享中央存储库的情况下,如果提交了一个文件,只有自己会拥有该文件的最新版本,其他团队成员拥有较旧的版本。为了让他们用存储库中的新版本替换本地副本,需要选择“Team | Update”。Eclipse会比较存储库中的文件副本和工作区中的文件副本:
- 如果工作区副本与最新版本匹配,将跳过该文件。
- 如果工作区副本与先前版本匹配,则会用CVS中的最新副本替换工作区版本。
在每个人的工作会话开始时,都应该使用“Update”功能查看应用程序的更改情况。需要注意的是,可以在项目级别进行更新和提交,这将使Eclipse对项目中的每个文件(包括子目录中的文件)进行更新或提交。
如果工作区副本既不与先前版本匹配,也不与当前版本匹配,则会发生冲突。Eclipse不会覆盖工作区副本,而是会发出警报,询问是使用本地副本、覆盖本地副本还是合并两个版本。前两个选项比较容易理解,合并则允许查看冲突并手动解决问题。选择合并时,Eclipse会在编辑器中打开文件,并插入特殊字符以突出显示源代码中的冲突,例如:
Workspace and CVS versions of changes are delimited with brackets (<, >) and equals signs (=).
In the first set, we see the version on the workspace.
<<<<<<< ViewCats.php
// This comment is supposed to trigger a conflict
=======
In the second set, we see the version that was in CVS.
=======
// So is this conflict.
>>>>>>> 1.3
解决冲突需要我们决定是接受自己的代码更改还是接受同事的更改。在解决冲突之前,需要了解是谁提交了先前版本的文件,这就需要查看CVS Annotate和CVS Resource History视图。
4. CVS Annotate视图
CVS Annotate和CVS Resource History视图紧密配合,用于展示文件的发展历程。我们可以对源代码进行一个小更改,来看看这两个视图如何帮助我们。
在
clsCatView.php
类中,添加一个小函数,当传入一个ID号时返回一个包含猫的字段的数组:
public function getACat($id, $dbConn)
{
$sql = "SELECT * FROM tCat WHERE CatID = " . $id;
$e = mysql_query($sql, $dbConn);
return mysql_fetch_array($e);
}
保存并提交该文件后,导航器视图应显示本地版本号为1.2。右键单击该文件,选择“Team | Show Annotation”,激活CVS Annotate视图。
默认情况下,CVS Annotate视图出现在工作台的左侧。该视图的理念是展示文件的当前状态以及它是如何演变而来的。它会将文件进行分段,大致显示出每个部分是在哪个版本中添加的以及由谁添加的。点击CVS Annotate视图中的某个部分,编辑器中相应的代码块会被高亮显示。
5. CVS资源历史视图
CVS资源历史视图从不同的角度提供了关于文件更改的更多信息。CVS Annotate视图关注文件的当前状态,而CVS资源历史视图则展示文件的过去版本。在该视图中,可以看到文件的每个版本,并进行版本间的比较。该视图位于编辑器下方,每一行显示文件的版本、标签(稍后会详细介绍)、提交的日期和时间、提交者以及他们输入的注释。在左侧的标签查看器中可以看到文件所属的每个标签和分支,右侧的注释查看器中可以看到完整的注释。这两个查看器都可以在该面板的选项菜单中开启或关闭。
该视图有一个非常有用的逐行比较功能,可用于比较两个版本的源代码。使用方法如下:
1. 高亮显示要比较的两个版本(使用Shift键选择第二个文件)。
2. 右键单击其中一个版本,选择“Compare”。Eclipse会启动一个文本查看器,将两个版本并排显示。
查看器会突出显示一侧缺失的文本,并指向另一侧相应的位置。例如,新函数会显示在旧文件的结束花括号下方。如果在较新的文件中删除了某些行,比较结果会相反,删除的代码块会被高亮显示,指针线会显示该代码块在早期版本中的位置。需要注意的是,该功能至少需要CVS 1.11或更高版本才能使用。对于Macintosh用户,需要使用Mac OS 10.4(Tiger)并通过XCode获取该版本;在较旧的Mac OS X版本中,需要从源代码编译自己的CVS版本。
6. 标签操作
在开发过程中,我们会将代码发布到测试、生产环境,甚至可能将其交付给其他团队。此时,为代码添加标签是一个很好的做法。CVS允许为文件添加版本标签,标签不仅仅是注释,它还能表明一组文件之间的关联。例如,开发一个包含一百个文件的Web应用程序,正在开发一个涉及其中五十个文件的新功能,在部署时,通过标签就能清楚知道需要推送哪些文件。
为项目添加标签的步骤如下:
1. 在导航器中右键单击项目,选择“Team | Tag As Version”,会弹出“Tag Resources”对话框。
2. 为标签命名。标签名称有一定限制,必须以字母开头,只能包含字母、数字、下划线或连字符。除此之外,应该创建自己的标签命名约定。
3. 如果标签名称已经存在,勾选“Move tag if it already exists”复选框,将标签移动到要标记的新版本。
4. 点击“OK”按钮创建标签。CVS会悄悄完成此操作,操作完成后会返回当前工作透视图,CVS中不会有明显变化。
7. 分支操作
分支操作与版本标签类似,但有一个显著区别——它将代码从Head中分离出来,这样可以在不影响生产环境中使用的代码的情况下继续进行开发。开发完成后,可以使用Eclipse将代码合并回Head。
下面以添加查看可领养狗的功能为例,介绍分支操作的步骤:
1. 在导航器视图中,右键单击项目名称ShelterSite,选择“Team | Branch…”,弹出“Create a new CVS Branch”对话框。
2. 为分支命名为Dogs,CVS会自动创建一个版本名称。点击“OK”按钮,分支创建完成。此时,CVS中实际上有了应用程序的两个版本。
3. 我们需要创建一个新的Dog类,它与Cat类非常相似,只需将所有“Cat”替换为“Dog”。切换回PHP透视图,通过“Save As”将
clsCat.php
文件另存为
clsDog.php
,并放在同一目录下。该文件与
clsCat.php
的唯一区别在于前几行代码,如下所示:
<?php
require_once("clsPet.php");
class Dog extends Pet
{
private $dogID;
private $name;
private $gender;
private $age;
private $breed;
public function setDogID($dogID) { $this->dogID = $dogID; }
public function getDogID() { return $this->dogID; }
-
保存并提交该文件。Eclipse会提示
clsDog.php文件不在CVS存储库中,询问是否要添加,点击“Yes”。当Eclipse要求输入注释时,可注明此次提交添加了新的Dog类。
虽然此时看不到,但CVS现在维护着源代码的两个副本,一个是Head部分,另一个是Dog分支。可以通过以下步骤从CVS中检出分支和Head到新项目,以验证确实存在两个版本,同时也能了解Eclipse如何从CVS中拉取整个项目:
1. 在导航器视图中创建一个新项目,命名为ShelterSite-Head。
2. 选择“File | Import…”启动导入向导,选择“Checkout Projects from CVS”,然后点击“Next”。
3. 选择我们创建的存储库,点击“Next”。
4. 在“Select Module”对话框中选择ShelterSite模块,可以在“Use specified module name”框中输入确切名称,也可以通过“Use an existing module”选项浏览存储库中的模块。此时“Finish”按钮已启用,但不要点击,而是点击“Next”。
5. 在“Check Out As”框中选择“Check out into an existing project”,然后点击“Next”。选择要检出文件的项目ShelterSite-Head,保持目标文件夹名称为ShelterSite,点击“Next”。
6. 最后,在向导的最后一个屏幕上,选择要检出的标签。通常在进行检出、特殊提交以及导入/导出等操作时,都会出现这样的对话框,它允许我们指定要放入或拉取代码的项目版本。我们要检出Head的代码库,因此高亮显示该选项,然后点击“Finish”按钮。
在导航器视图中,会看到ShelterSite-Head项目中填充了一份不包含
clsDog.php
文件的应用程序副本。同样的操作也可以用于Dog分支,以查看包含
clsDog
类的完整应用程序版本。
8. 代码合并操作
合并是将两组代码库合并的操作。虽然Eclipse可以帮助我们完成合并,但这仍然是一个非常手动的过程,至少需要一名开发人员参与,通常是由两名分别熟悉不同代码库的开发人员协作完成。
在这个例子中,我们将比较Dog分支和Head分支,最终将更改合并回Head。实际上,通过利用标签和其他分支,我们在比较时并没有太多限制。通常,开发人员会先将自己的分支进行合并,然后再合并到Head。在某些环境中,普通开发人员不允许直接操作Head,这项工作由源管理员负责,他们会审查每一个进入Head的更改,开发人员只能在分支上工作。
发起合并的步骤如下:
1. 在导航器视图中选择一个项目,右键单击它,选择“Team | Merge…”。
2. 系统会询问要比较的两个版本。
3. 选择两个项目后,会进入团队同步透视图。
通过以上步骤,我们可以全面掌握CVS版本控制的各项功能,从项目的添加、提交和更新,到利用标签、分支进行版本管理,再到最终的代码合并,能够更好地管理和协作开发项目。
深入理解CVS版本控制:从项目添加到代码合并
9. 合并操作的注意事项与冲突解决
在进行代码合并时,可能会遇到各种情况,尤其是冲突问题。如前面提到的,当工作区副本与存储库版本不匹配时就会发生冲突。为了更清晰地理解冲突解决过程,我们可以用一个流程图来表示:
graph TD;
A[开始合并] --> B{是否有冲突};
B -- 否 --> C[合并完成];
B -- 是 --> D{选择解决方式};
D -- 使用本地副本 --> E[保留本地版本];
D -- 覆盖本地副本 --> F[使用存储库版本];
D -- 合并两个版本 --> G[手动解决冲突];
E --> C;
F --> C;
G --> H[编辑文件解决冲突];
H --> I[再次提交合并结果];
I --> C;
当选择合并两个版本时,Eclipse会在编辑器中打开文件,并插入特殊字符来标记冲突。例如:
<<<<<<< ViewCats.php
// This comment is supposed to trigger a conflict
=======
// So is this conflict.
>>>>>>> 1.3
我们需要仔细审查这些冲突,决定是接受自己的更改还是同事的更改。在解决冲突时,可以参考CVS Annotate和CVS Resource History视图中的信息,了解谁提交了先前版本以及代码的演变过程。
10. 标签和分支的应用场景对比
标签和分支在版本控制中都有重要的作用,但它们的应用场景有所不同。下面通过一个表格来对比它们的特点和适用场景:
| 功能 | 特点 | 适用场景 |
| — | — | — |
| 标签 | - 标记特定版本,表明一组文件的关联
- 不改变代码结构
- 方便版本回溯和部署 | - 代码发布到测试、生产环境时标记版本
- 记录重要的里程碑版本,如发布版本、稳定版本 |
| 分支 | - 将代码从主分支分离,独立开发
- 可以并行开发多个功能,不影响主分支代码
- 开发完成后可合并回主分支 | - 开发新功能、修复漏洞时避免影响主分支
- 进行实验性开发,不确定是否要合并到主分支 |
例如,在开发一个新功能时,如果该功能的开发周期较长,且可能会对现有代码产生较大影响,就可以使用分支进行独立开发。而当代码达到一个稳定的阶段,如完成一个版本的开发并准备发布到生产环境时,就可以使用标签来标记这个版本。
11. 版本控制的最佳实践
为了更好地使用CVS进行版本控制,以下是一些最佳实践建议:
-
定期提交和更新
:养成定期提交代码的习惯,每次提交时添加详细的注释,说明更改的内容和目的。同时,在开始工作前先进行更新,确保使用的是最新版本的代码。
-
合理使用标签和分支
:根据项目的需求和开发阶段,合理使用标签和分支。标签用于标记重要的版本,分支用于独立开发新功能或修复漏洞。
-
及时解决冲突
:当发生冲突时,及时与团队成员沟通,共同解决冲突。避免冲突积累,导致后续合并困难。
-
建立代码审查机制
:在代码合并到主分支之前,进行代码审查,确保代码的质量和一致性。
-
备份存储库
:定期备份CVS存储库,以防数据丢失。
12. 总结
通过本文,我们详细介绍了CVS版本控制的各项功能,包括项目的添加、提交和更新,以及标签、分支和合并等操作。掌握这些功能可以帮助我们更好地管理项目的版本,提高团队协作效率。
在实际应用中,我们需要根据项目的需求和团队的协作方式,合理运用这些功能。同时,遵循版本控制的最佳实践,确保代码的质量和可维护性。希望本文能为你在使用CVS进行版本控制时提供有价值的参考。
超级会员免费看
756

被折叠的 条评论
为什么被折叠?



