关键字替换
关键字替换
Subversion具备添加关键字的能力—一些有用的,关于版本化的文件动态信息的片断—不必直接添加到文件本身。关键字通常会用来描述文件最后一次修改的一些信息,因为这些信息每次都有改变,更重要的一点,这是在文件修改之后,除了版本控制系统,对于任何企图保持数据最新的过程都是一场混乱,作为人类作者,信息变得陈旧是不可避免的。
举个例子,你有一个文档希望显示最后修改的日期,你需要麻烦每个作者提交之前做这件事情,也要修改文档的一部分来描述何时作的修改,但是迟早会有人忘记做这件事,不选择简单的告诉Subversion来执行替换LastChangedDate
关键字的操作,你通过在目标位置放置一个keyword anchor来控制关键字插入的位置,这个anchor只是一个格式为$
KeywordName
$
字符串。
所有作为anchor出现在文件里的关键字是大小写敏感的:为了关键字的扩展,你必须使用正确的大写,你必须考虑svn:keywords
的属性值也是大小写敏感—特定的关键字名会忽略大小写,但是这个特性已经被废弃了。
Subversion定义了用来替换的关键字列表,这个列表保存了如下五个关键字,有一些也包括了可用的别名:
Date
这个关键字保存了文件最后一次在版本库修改的日期,看起来类似于
$Date: 2006-07-22 21:42:37 -0700 (Sat, 22 Jul 2006) $
,它也可以用LastChangedDate
来指定。Revision
这个关键字描述了这个文件最后一次修改的修订版本,看起来像
$Revision: 144 $
,也可以通过LastChangedRevision
或者Rev
引用。Author
这个关键字描述了最后一个修改这个文件的用户,看起来类似
$Author: harry $
,也可以用LastChangedBy
来指定。HeadURL
这个关键字描述了这个文件在版本库最新版本的完全URL,看起来类似
$HeadURL: http://svn.collab.net/repos/trunk/README $
,可以缩写为URL
。Id
这个关键字是其他关键字一个压缩组合,它看起来就像
$Id: calc.c 148 2006-07-28 21:30:43Z sally $
,可以解释为文件calc.c
上一次修改的修订版本号是148,时间是2006年7月28日,作者是sally
。
前面的一些描述使用了类似“最后已知的”短语,请记住关键字扩展是客户端操作,你的客户端只“知道”在你更新工作拷贝时版本库发生的修改,如果你从不更新工作拷贝,即使文件在版本库里有规律的修改,这些关键字也不会扩展为不同的值。
只在你的文件增加关键字anchor不会做什么特别的事情,Subversion不会尝试对你的文件内容执行文本替换,除非明确的被告知这样做,毕竟,你可以撰写一个关于如何使用关键字的文档[14],你不希望Subversion会替换你漂亮的关于不需要替换的关键字anchor实例!
为了告诉Subversion是否替代某个文件的关键字,我们要再次求助于属性相关的子命令,当svn:keywords
属性设置到一个版本化的文件,这些属性控制了哪些关键字将会替换到这个文件,这个属性的值是空格分隔的前面列表的名称或是别名列表。
举个例子,假定你有一个版本化的文件weather.txt
,内容如下:
Here is the latest report from the front lines. $LastChangedDate$ $Rev$ Cumulus clouds are appearing more frequently as summer approaches.
当没有svn:keywords
属性设置到这个文件,Subversion不会有任何特别操作,现在让我们允许LastChangedDate
关键字的替换。
$ svn propset svn:keywords "Date Author" weather.txt property 'svn:keywords' set on 'weather.txt' $
现在你已经对weather.txt
的属性作了修改,你会看到文件的内容没有改变(除非你之前做了一些属性设置),注意这个文件包含了Rev
的关键字anchor,但我们没有在属性值中包括这个关键字,Subversion会高兴的忽略替换这个文件中的关键字,也不会替换svn:keywords
属性中没有出现的关键字。
在你提交了属性修改后,Subversion会立刻更新你的工作文件为新的替代文本,你将无法找到$LastChangedDate$
的关键字anchor,你会看到替换的结果,这个结果也保存了关键字的名字,与美元符号($
)绑定在一起,而且我们预测的,Rev
关键字不会被替换,因为我们没有要求这样做。
注意我们设置svn:keywords
属性为“Date Author”,关键字anchor使用别名$LastChangedDate$
并且正确的扩展。
Here is the latest report from the front lines. $LastChangedDate: 2006-07-22 21:42:37 -0700 (Sat, 22 Jul 2006) $ $Rev$ Cumulus clouds are appearing more frequently as summer approaches.
如果有其他人提交了weather.txt
的修改,你的此文件的拷贝还会显示同样的替换关键字值—直到你更新你的工作拷贝,此时你的weather.txt
重的关键字将会被替换来反映最新的提交信息。
$GlobalRev$在哪里?
新用户经常为如何使用$Rev$
关键字迷惑,自从版本库有了单独的全局增长的修订版本号码,许多人以为$Rev$
关键字是反映修订版本号码的,但实际上$Rev$
是文件最后修改的修订版本,而不是最后更新的。理解这一点,会减少一些混淆,但是还有一些挫折—如果没有Subversion关键字的支持,你怎么才能在你的文件自动得到全局修订版本号到。
为此你需要外置处理,Subversion中有一个工具svnversion就是为此设计。svnversion遍历你的工作拷贝,然后输出它发现的修订版本,你可以使用这个程序,外加一些工具,将修订版本信息嵌入到你的文件。关于svnversion的更多信息,见“ svnversion ”一节。
Subversion 1.2引入了另一种关键字的语法,提供了额外和有用的,尽管是非典型的功能。你现在可以告诉Subversion为替代的关键字维护一个固定长度(从消耗字节的观点),通过在关键字名后使用双冒号(::
),然后紧跟一组空格,你就定义了固定宽度。当Subversion使用替代值代替你的关键字,只会替换这些空白字符,保持关键字字段长度保持不变,如果替代值比定义的字段短,会有替代字段后保留空格;如果替代值太长,就会在最后的美元符号终止符前用井号(#
)截断。
例如,你有一篇文档,其中一段是一些反映Subversion关键字的表格数据,使用原始的Subversion关键字替换语法,你的文件或许像这样:
$Rev$: Revision of last commit $Author$: Author of last commit $Date$: Date of last commit
现在,表格看起来佷漂亮,但是当你提交文件(当然,关键字替换功能已打开),你会看到:
$Rev: 12 $: Revision of last commit $Author: harry $: Author of last commit $Date: 2006-03-15 02:33:03 -0500 (Wed, 15 Mar 2006) $: Date of last commit
结果并不漂亮,你可能会尝试重新调整文件使之更像一个列表。只有关键字的长度是相同的时候才能保证保持样式,如果进入另一个修订版本(如从99到100),或者是另一个有较长用户名的人提交了文件,表格又会变形。然而,如果你使用Subversion 1.2,你可以使用新的固定长度的关键字语法,定义合适的字段宽度,然后你的文件可能如此:
$Rev:: $: Revision of last commit $Author:: $: Author of last commit $Date:: $: Date of last commit
你提交这个文件的修改,这一次Subversion注意到了新的固定长度的关键字语法,根据你在双冒号之间指定的空格长度调整格式,并且紧跟一个美元符号。经过替换,字段的长度没有发生变化—Rev
和Author
多了一些空格,而较长的Date
字段被一个分号截断:
$Rev:: 13 $: Revision of last commit $Author:: harry $: Author of last commit $Date:: 2006-03-15 0#$: Date of last commit
固定长度关键字在执行复杂文件格式的替换中非常易用,也可以处理那些很难通过其他程序(例如Microsoft Office文档)进行修改的文件。
警告
需要意识到,因为关键字字段的长度是以字节为单位,可能会破坏多字节值,例如一个用户名包含多字节的UTF-8字符,可能会遭遇从某个字符中间截断的情况,从字节角度看仅仅是一种截断,但是从UTF-8字符串角度看可能是错误和曲解的,当载入文件时,破坏的UTF-8文本可能导致整个文件的破坏,整个文件无法操作。所以,当限制关键字为固定大小时,需要选择一个可以扩展的大小。
[14] … 或者可能是一本书的一个小节 …