CVS:超越 RCS 的版本控制

作者:Tom Morse

CVS(Concurrent Versions System,并发版本系统)是一个版本控制系统。借助 CVS,开发者能够查看任何源文件的更改历史记录,检索特定文件的任何版本,避免互相覆盖彼此的更改,并跟踪发布版本以及与之关联的文件版本。

首先,简要介绍一下 CVS 的一些概念。项目的所有源代码都存储在一个名为仓库的中心位置。仓库中的源代码被组织成模块。通常,每个模块代表一个单独的项目。一个模块可以代表任意数量的文件和目录。

当开发者希望使用特定的一组源代码时,他可以使用 CVS 检索这些源代码的本地副本。这个本地副本可以代表每个文件的最新版本或某些过去的版本。

典型的版本控制系统要求用户“锁定”他希望编辑的每个文件,防止其他开发者编辑这些文件,直到第一个用户提交了他的更改。这可能会非常耗时,因为开发者要么互相等待提交更改,要么同时工作,然后在稍后手动合并更改。CVS 通过允许并发编辑解决了这个问题。

并发编辑允许多个开发者同时处理相同的文件。通常,并发编辑会导致一个开发者覆盖另一个开发者先前提交的更改。

CVS 通过强制开发者将自他检索该文件的本地副本以来已提交到仓库文件中任何更改合并到其本地副本中,来防止覆盖。只有这样,开发者才能提交他的更改。这个过程大部分是自动的,但是,例如,如果在仓库和本地副本中的同一行代码中都进行了更改,则需要手动解决冲突。

...的一天生活,

让我们看看我们的软件开发团队是如何工作的。由于他们项目的保密性,所有文件名都已更改,以保护无辜者。他们的项目是“制造更好的捕鼠器”。

修复 Bug

Fezzik 虽然主要是一名文档编写者,(这解释了为什么我们团队的所有手册都是用韵文写的。)但在他的工作中,也会进行一些软件 bug 的检测和消除。让我们看看 Fezzik 如何修复产品先前版本中的一个关键 bug。

产品的 4.0 版本在几个月前发布了。现在,一位非常重要的客户发现了一个关键 bug。必须在已发布版本的软件中修复此 bug,为客户制作一个点发布版本,并且必须将此修复合并到软件的工作版本中。

在调查问题时,Fezzik 确定 bug 是在软件的 3.3 和 4.0 版本之间引入的。他的第一步是获取 4.0 版本的源代码副本。他使用以下命令来执行此操作

cvs checkout -r PROD_REL4-0 mousetrap

这将检出整个项目的所有目录和源代码文件。每个源文件的版本将是包含在名为 PROD_REL4-0 的发布版本中的版本,不包括自发布以来对该源文件所做的任何更改。

现在 Fezzik 有了一个名为 mousetrap 的新目录。此目录中包含所有项目源代码,就像发布 4.0 时一样。由于自发布 4.0 以来项目开发仍在继续,Fezzik 必须从这一点开始在修订树上创建一个新分支。他使用以下命令

cvs tag -b POINT_RELS_REL4-0
cvs update -r POINT_RELS_REL4-0

修订树将如下所示

                    |HEAD - dev for next full release
POINT_RELS_REL4-0\  |
                  \ |
                   \|
                    +PROD_REL4-0
                    |
                    |
                    |
                    +PROD_REL3-3
                    |
                    |

Fezzik 本可以在检出项目之前创建分支标签,从而从他使用的方法中消除一个步骤。以下序列将产生与上述相同的效果

cvs rtag -b -r PROD_REL4-0 POINT_RELS_REL4-0 mousetrap
cvs checkout -r POINT_RELS_REL4-0

CVS 有许多命令和选项组合。因此,通常有不止一种方法可以产生相同或相似的结果。这种灵活性使 CVS 能够适应各种开发流程。

Fezzik 怀疑文件 cheese.c 包含 bug,因此他决定查看在 3.3 和 4.0 版本之间对该文件所做的所有更改。为此,他使用 diff 命令

cvs diff -r PROD_REL3-3 cheese.c

这会生成一个列表,列出当前目录中 cheese.c 文件与 PROD_REL3-3 中使用的版本之间的差异。Fezzik 本可以指定第二个版本,使用

-r PROD_REL4-0

并产生相同的效果。

在查看差异时,Fezzik 找到了他认为是他正在寻找的 bug。他想与进行更改的人员确认他计划进行的任何修改,因此他查看了 cheese.c 的日志文件。

cvs log cheese.c

他看到在两个版本之间只有 Buttercup 修改了这个文件,因此他可以与她讨论修复方案。在进行修复并测试后,Fezzik 准备提交他的更改。他从项目的顶层目录发出以下命令

cvs commit -m "修复了 bug #1202"

Fezzik 没有指定要提交的特定文件,因此此命令将提交此目录以及其所有子目录中(递归地)所有已修改的文件。每个提交的文件都将添加消息“修复了 bug #1202”作为日志消息。由于此修复将发送给客户,Fezzik 决定标记将要发送的文件集

cvs tag PROD_REL4-0-1

现在 Fezzik 需要创建要发送给客户的补丁文件

cvs rdiff -r PROD_REL4-0 -r PROD_REL4-0-1 mousetrap > patch4.0-4.0.1

这会创建一个 Larry Wall 格式的补丁文件,客户可以将该文件馈送到 patch 程序中以更新其源代码。这些补丁会将客户的 4.0 源代码更新到新的 4.0.1 源代码。

现在 Fezzik 需要将修复合并到当前的开发源代码中。首先,他使用以下命令将其源代码更新到主线程上的最新版本

cvs update -A

这具有与删除模块的本地副本并对模块进行新的检出相同的效果,从而获得最新的版本。

然后,他使用以下命令让 CVS 自动合并来自 4.0.1 点发布版本的更改

cvs update -j PROD_REL4-0-1

CVS 会自动将 Fezzik 在分支上所做的更改合并到这些最新的源代码中。如果合并两组源代码导致冲突,CVS 将会声明这一点。在文件中的冲突点,将会有分隔的区域,其中包含来自两个源的文本。这些区域将需要手动合并。

一旦一切都合并完成,Fezzik 可以使用另一个 commit 命令提交所有更改

cvs commit -m "合并了 PROD_REL4-0-1 中的修复"

争用

现在我们转向 Westley,他将演示在多人项目中使用 CVS 的方法。

Westley 已经离开项目一个月了 [考虑到他曾经死过,这并不太令人惊讶]。他需要做的第一件事是更新他的源代码。

cvs update

由于自上次提交以来他没有修改任何内容,因此一切都只是更新;不可能存在冲突。现在 Westley 想要查看自 4 月 10 日他离开后发生了什么。他使用以下命令查看 4 月 10 日之后进行的提交的所有日志消息

cvs log -d>4/10 -b

在查看日志文件后,他感觉已经跟上了进度,因此他立即开始修改源代码。在他的工作过程中,他需要创建一个新文件 happiness.c。在磁盘上创建文件 happiness.c 后,他发出以下命令

cvs add happiness.c

Westley 还废弃了一个文件,删除该文件后,他发出以下命令

cvs delete agony.c

add 和 delete 命令只有在完成 CVS 提交后才会完全生效。

经过一天的工作,Westley 添加了一个新功能,并准备提交他的修改。他发出以下命令

cvs commit -m "做了一些很棒的改进"

CVS 通知他,其他人已经提交了他修改过的某些文件的更改,因此他必须先使用其他开发者的更改更新他的文件,然后才能提交自己的更改。一个简单的 update 命令调用就可以做到这一点

cvs update

在手动编辑以解决他的更改与已提交到仓库的更改之间的任何冲突后,Westley 再次测试了他的新功能。一切看起来都很好,所以他再次尝试提交

cvs commit -m "做了一些很棒的改进"

这次成功了。这种工作方法相对于许多系统来说是一个很大的改进,在许多系统中,一个人必须先锁定一个文件才能对其进行编辑,而任何想要编辑该文件的其他人必须等到第一个人提交更改并解锁该文件后才能进行编辑。

发布

现在 Buttercup 将演示如何发布新版本的软件。她首先检出最新的源代码。

cvs checkout mousetrap

在验证这些源代码是应该发布的准确版本后,她标记发布版本

cvs tag PROD_REL4-1

然后,她使用 export 命令创建一组目录,其中包含要交付的所有源代码

cvs export -R PROD_REL4-1 mousetrap

这将创建一个目录结构,其中仅填充正确的源代码,而不包含任何 CVS 管理目录或文件。

总结

CVS 的全部功能超出了本文的范围,但我希望我已经提供了足够的介绍来吸引您尝试 CVS。我们在 Lernout & Hauspie 已经使用了 5 个月,并且对其性能非常满意。

Per Cederqvist 撰写了一篇关于 CVS 的优秀介绍,名为 Version Management with CVS(使用 CVS 进行版本管理)。可以在 WWW 上找到它,方法是访问 CVS 页面上的链接:http://www.winternet.com/~zoo/cvs/。本手册将包含在 CVS 的下一个版本 1.4 版中。

有关此软件开发团队之前的冒险经历,请参阅(或阅读)William Goldman 的 The Princess Bride(公主新娘)。

Tom Morse (tmorse@lhs.com) 在过去 10 年中一直在 Unix 领域工作,目前在 Lernout & Hauspie Speech Products 工作。当他不被束缚在电脑前时,他会花时间进行山地自行车、徒步旅行和尝试学习荷兰语。

加载 Disqus 评论