典型工程师的一个特质就是会对潜在问题区域高度敏感,对于软件工程师来说,这通常意味着当在代码块中工作时会在间接视觉中定位可能的问题,这是祝福也是诅咒。你希望
bug 被修正,但是我们经常会在追求完美的过程中脱离了主要任务。
另一个开发者生活的事实就是他们总有许多事情无法按时完成,而且每一件事都对某些人有最高的优先级,因此,我们发现自己经常在同一时间作许多事情,结果所有的事情进展都会很缓慢,至少你可以凭良心和强迫的微笑:
” 正在处理,我正在为此事工作。 ”
我的管理读者,我必须承认我对那些问题绝对没有办法,毕竟这是一个技术 blog
。但是我可以(也会)告诉你一个即将到来的 Subversion 特性,可以减少这类开发者的环境转换: changelists
。
无论什么原因,开发者经常会在任何给定时间修改代码中显著不同的东西,经常是每个修改没有精细的保存在一些模块中,没有安全的与其它修改分离。修改的组会重叠,修改同一个模块的不同文件,甚至是同一文件的不同行。开发者有许多工作方法可以采用来保持任务的组织性,一些用户使用同一个版本库的不同工作拷贝来保存每个单独的修改过程,另外一些人会在版本库创建一个特性分支,使用单独的工作拷贝经常会指向某个分支,也有一些人使用
diff 和 patch 来备份和恢复未提交的修改,使用补丁文件来关联每一次修改。这些方法都有其利弊,更大程度上,要做的修改的细节制定了区分它们的方法学。
但是在 Subversion 1.5 我们有了一个新特性叫做 ”changelists”
,另一种处理混合的方法。 changelists 基本上是以关联多个文件一起为目的的,应用到工作拷贝文件上的任意标签,
Gmail 用户对于这个概念已经非常熟悉, Gmail 没有提供传统的目录为基础的邮件组织机制,在 Gmail
里,你可以为邮件附加任意的标签,所以多个共享同一个标签的邮件成为同一个组的一部分,所以察看具备相同标签的邮件成为一个简单的用户技巧。许多
Web 2.0 的站点具备类似的机制 - 考虑 YouTube 和 Flickr 等站点使用的 ” 标签(
tags ) ” , blog 条目的 ” 分类( categories ) ” 等等。现在的人们知道组织数据的困难,但是数据的组织应该是一个灵活的概念,以前的文件目录组织方式对于大多数应用过于严格了。
所以 Subversion 的 changelist 支持允许你:
- 给需要与 changelist 关联的文件应用标签( labels )
- 删除标签,而且
- 限制子命令操作的对象仅限于特定标签。
例如,作为我今天要完成任务的一部分,我需要修正一 些 ViewVC 的
diff 察看相关功能的问题,我的工作需要修改一组文件。
$ cd projects/viewvc
$ svn status
M
lib/vclib/ccvs/__init__.py
M
lib/vclib/__init__.py
$
但是当我测试这些修改的时候,我发现一些注释支持的代码不能正常工作。因此,就像前面提到的,此刻为了转换上下文环境并修改次要问题我可以做很多事情,为了描述我们将会使用
changelists 。
首先,我想创建一个 changelists 与我已经修改的文件关联,这样可以帮助我将次要问题将要修改的文件区分开来。
$ svn changelist diff-fixes lib/vclib/ccvs/__init__.py
Path ‘lib/vclib/ccvs/__init__.py’ is
now a member of changelist ‘diff-fixes’.
$ svn changelist diff-fixes lib/vclib/__init__.py
Path ‘lib/vclib/__init__.py’ is now
a member of changelist ‘diff-fixes’.
$ svn status
— Changelist ‘diff-fixes’:
M
lib/vclib/ccvs/__init__.py
M
lib/vclib/__init__.py
$
就像你看到的, ”svn status” 的输出反映了新的分组。
现在我开始修正次要问题,需要我修改三个文件,我还没有准备好提交任何文件,所以我对第二次修改也创建一个
changelist 。
$ svn changelist blame-fix lib/vclib/ccvs/blame.py
Path ‘lib/vclib/ccvs/blame.py’ is now
a member of changelist ‘blame-fix’.
$ svn status
— Changelist ‘blame-fix’:
M
lib/vclib/ccvs/blame.py
— Changelist ‘diff-fixes’:
M
lib/vclib/ccvs/__init__.py
M
lib/vclib/__init__.py
$
现在,独一无二的分组看起来很好,但并不是完全有用。如果我希望只是察看 diff
相关的代码变更,在 ”svn diff” 中,我仍然需要我所修改文件的明确文件名。
$ svn diff lib/vclib/__init__.py lib/vclib/ccvs/__init__.py
这对于两个文件并不太难,但是如果是 20 个文件呢?
幸运的是, Subversion 1.5 的 changelist 支持更加彻底,我可以使用新的
–changelist 选项来限定许多子命令只关联给定 changelist 的文件,结果就是更简单的命令行,以及更简单的来俯瞰我希望检查的文件。
$ svn diff --changelist diff-fixes
Index: lib/vclib/ccvs/__init__.py
— lib/vclib/ccvs/__init__.py
(revision 1157)
+++ lib/vclib/ccvs/__init__.py
(working copy)
@@ -112,8 +112,8 @@
temp2 = tempfile.mktemp()
open(temp2, ‘wb’).write(self.openfile(path_parts2,
rev2)[0].getvalue())
+
r1 = self.itemlog(path_parts1, rev1,
{})[-1]
+
r2 = self.itemlog(path_parts2, rev2,
{})[-1]
info1 = (self.rcsfile(path_parts1, root=1,
v=0), r1.date, r1.string)
info2 = (self.rcsfile(path_parts2, root=1,
v=0), r2.date, r2.string)
Index: lib/vclib/__init__.py
— lib/vclib/__init__.py
(revision 1157)
+++ lib/vclib/__init__.py
(working copy)
@@ -240,7 +241,7 @@
def readline(self):
return self.fp.readline()
-
def close():
+
def close(self):
try:
if self.fp:
self.fp.close()
$
就像你预期的,我可以在 ”svn commit” 中提供同样的 –changelist
选项。
$ svn ci -m "Fix some diff-related
oopses." --changelist diff-fixes
Sending
lib/vclib/ccvs/__init.py
Sending
lib/vclib/__init.py
Transmitting file data ..
Committed revision 1158.
$
同时,我的其他 changelist 依然没有被打扰。
$ svn st
— Changelist ‘blame-fixes’
M
lib/vclib/ccvs/blame.py
$
许多 Subversion 客户端子命令( commit, diff,
info, lock, log, proplist, propget, propset, status,
update, …). )出现了新的 –changelist 选项,而且,当然也有了新的 ”svn changelist”
子命令,用来从 changelist 添加和删除(通过一个 –remove 选项)文件。
Subversion 没有强制你使用 changelist ,就像大多数事情,
Subversion 只是提供给你这个工具,让你决定是否使用它。总之,这个特性给了 Subversion
用户,特别是有 Perforce 经验的用户 - 同时管理多个进行工作的一个简单方法。
changelist 支持也有一些限制,首先,这个特性是路径粒度的特性,如果你发现你有同一个文件的重叠修改,你需要找出不同的方法来处理重叠。同样,
changelist 只是对于特定工作拷贝私有 - 无法自动与其他用户分享你的 changelist 定义,但是解决这个特性不是什么大问题
- 如果你需要共享进行中的工作,使用版本化的分支。
|