1.关键字替换

Posted on Posted in 4.高级主题

关键字替换

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] … 或者可能是一本书的一个小节 …