SVN Keyword Substitution

Keyword Substitution
Subversion has the ability to substitute keywords—pieces of useful, dynamic information about a versioned file—into the contents of the file itself. Keywords generally provide information about the last modification made to the file. Because this information changes each time the file changes, and more importantly, just after the file changes, it is a hassle for any process except the version control system to keep the data completely up-to-date. Left to human authors, the information would inevitably grow stale.

For example, say you have a document in which you would like to display the last date on which it was modified. You could burden every author of that document to, just before committing their changes, also tweak the part of the document that describes when it was last changed. But sooner or later, someone would forget to do that. Instead, simply ask Subversion to perform keyword substitution on the LastChangedDate keyword. You control where the keyword is inserted into your document by placing a keyword anchor at the desired location in the file. This anchor is just a string of text formatted as $KeywordName$.

All keywords are case-sensitive where they appear as anchors in files: you must use the correct capitalization in order for the keyword to be expanded. You should consider the value of the svn:keywords property to be case-sensitive too—certain keyword names will be recognized regardless of case, but this behavior is deprecated.

Subversion defines the list of keywords available for substitution. That list contains the following five keywords, some of which have aliases that you can also use:

  • Date
  • This keyword describes the last time the file was known to have been changed in the repository, and is of the form $Date: 2006-07-22 21:42:37 -0700 (Sat, 22 Jul 2006) $. It may also be specified as LastChangedDate.
  • Revision
  • This keyword describes the last known revision in which this file changed in the repository, and looks something like $Revision: 144 $. It may also be specified as LastChangedRevision or Rev.
  • Author
  • This keyword describes the last known user to change this file in the repository, and looks something like $Author: harry $. It may also be specified as LastChangedBy.
  • HeadURL
  • This keyword describes the full URL to the latest version of the file in the repository, and looks something like $HeadURL: http://svn.collab.net/repos/trunk/README $. It may be abbreviated as URL.
  • Id
  • This keyword is a compressed combination of the other keywords. Its substitution looks something like $Id: calc.c 148 2006-07-28 21:30:43Z sally $, and is interpreted to mean that the file calc.c was last changed in revision 148 on the evening of July 28, 2006 by the user sally.

Several of the previous descriptions use the phrase “last known” or similar wording. Keep in mind that keyword expansion is a client-side operation, and your client only “knows” about changes which have occurred in the repository when you update your working copy to include those changes. If you never update your working copy, your keywords will never expand to different values even if those versioned files are being changed regularly in the repository.

Simply adding keyword anchor text to your file does nothing special. Subversion will never attempt to perform textual substitutions on your file contents unless explicitly asked to do so. After all, you might be writing a document [14] about how to use keywords, and you don't want Subversion to substitute your beautiful examples of un-substituted keyword anchors!

To tell Subversion whether or not to substitute keywords on a particular file, we again turn to the property-related subcommands. The svn:keywords property, when set on a versioned file, controls which keywords will be substituted on that file. The value is a space-delimited list of the keyword names or aliases found in the previous table.

For example, say you have a versioned file named weather.txt that looks like this:

Here is the latest report from the front lines.
$LastChangedDate$
$Rev$
Cumulus clouds are appearing more frequently as summer approaches.
With no svn:keywords property set on that file, Subversion will do nothing special. Now, let's enable substitution of the LastChangedDate keyword.

$ svn propset svn:keywords "Date Author" weather.txt
property 'svn:keywords' set on 'weather.txt'
$
Now you have made a local property modification on the weather.txt file. You will see no changes to the file's contents (unless you made some of your own prior to setting the property). Notice that the file contained a keyword anchor for the Rev keyword, yet we did not include that keyword in the property value we set. Subversion will happily ignore requests to substitute keywords that are not present in the file, and will not substitute keywords that are not present in the svn:keywords property value.

Immediately after you commit this property change, Subversion will update your working file with the new substitute text. Instead of seeing your keyword anchor $LastChangedDate$, you'll see its substituted result. That result also contains the name of the keyword, and continues to be bounded by the dollar sign ($) characters. And as we predicted, the Rev keyword was not substituted because we didn't ask for it to be.

Note also that we set the svn:keywords property to “Date Author” yet the keyword anchor used the alias $LastChangedDate$ and still expanded correctly.

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.
If someone else now commits a change to weather.txt, your copy of that file will continue to display the same substituted keyword value as before—until you update your working copy. At that time the keywords in your weather.txt file will be re-substituted with information that reflects the most recent known commit to that file.

Where's $GlobalRev$?

New users are often confused by how the $Rev$ keyword works. Since the repository has a single, globally increasing revision number, many people assume that it is this number which is reflected by the $Rev$ keyword's value. But $Rev$ expands to show the last revision in which the file changed, not the last revision to which it was updated. Understanding this clears the confusion, but frustration often remains—without the support of a Subversion keyword to do so, how can you automatically get the global revision number into your files?

To do this, you need external processing. Subversion ships with a tool called svnversion which was designed for just this purpose. svnversion crawls your working copy and generates as output the revision(s) it finds. You can use this program, plus some additional tooling, to embed that revision information into your files. For more information on svnversion, see the section called “svnversion”.

Subversion 1.2 introduced a new variant of the keyword syntax which brought additional, useful—though perhaps atypical—functionality. You can now tell Subversion to maintain a fixed length (in terms of the number of bytes consumed) for the substituted keyword. By using a double-colon (::) after the keyword name, followed by a number of space characters, you define that fixed width. When Subversion goes to substitute your keyword for the keyword and its value, it will essentially replace only those space characters, leaving the overall width of the keyword field unchanged. If the substituted value is shorter than the defined field width, there will be extra padding characters (spaces) at the end of the substituted field; if it is too long, it is truncated with a special hash (#) character just before the final dollar sign terminator.

For example, say you have a document in which you have some section of tabular data reflecting the document's Subversion keywords. Using the original Subversion keyword substitution syntax, your file might look something like:

$Rev$:     Revision of last commit
$Author$:  Author of last commit
$Date$:    Date of last commit
Now, that looks nice and tabular at the start of things. But when you then commit that file (with keyword substitution enabled, of course), you see:

$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
The result is not so beautiful. And you might be tempted to then adjust the file after the substitution so that it again looks tabular. But that only holds as long as the keyword values are the same width. If the last committed revision rolls into a new place value (say, from 99 to 100), or if another person with a longer username commits the file, stuff gets all crooked again. However, if you are using Subversion 1.2 or better, you can use the new fixed-length keyword syntax, define some field widths that seem sane, and now your file might look like this:

$Rev::               $:  Revision of last commit
$Author::            $:  Author of last commit
$Date::              $:  Date of last commit
You commit this change to your file. This time, Subversion notices the new fixed-length keyword syntax, and maintains the width of the fields as defined by the padding you placed between the double-colon and the trailing dollar sign. After substitution, the width of the fields is completely unchanged—the short values for Rev and Author are padded with spaces, and the long Date field is truncated by a hash character:

$Rev:: 13            $:  Revision of last commit
$Author:: harry      $:  Author of last commit
$Date:: 2006-03-15 0#$:  Date of last commit
The use of fixed-length keywords is especially handy when performing substitutions into complex file formats that themselves use fixed-length fields for data, or for which the stored size of a given data field is overbearingly difficult to modify from outside the format's native application (such as for Microsoft Office documents).

Warning
Be aware that because the width of a keyword field is measured in bytes, the potential for corruption of multi-byte values exists. For example, a username which contains some multi-byte UTF-8 characters might suffer truncation in the middle of the string of bytes which make up one of those characters. The result will be a mere truncation when viewed at the byte level, but will likely appear as a string with an incorrect or garbled final character when viewed as UTF-8 text. It is conceivable that certain applications, when asked to load the file, would notice the broken UTF-8 text and deem the entire file corrupt, refusing to operate on the file altogether. So, when limiting keywords to a fixed size, choose a size that allows for this type of byte-wise expansion.

svn propset svn:keywords "Date Author" test.php

svn proset svn:keywords "id" test.php

8。 如何设置svn自动属性
freebsd目录了为:/root/.subversion/

前面提到的文件属性要设置起来通过命令行的方式很麻烦,我们可以通过修改 Subversion的配置文件让Subsersion自动实行上面的操作。 具体做法如下:

修改 home/Subversion/config 文件。

将 enable-auto-props = yes

然后添加如下的内容[auto-props]

*.java = svn:eol-style=native;svn:keywords=Rev Date

*.xml = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

*.xsl = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

*.xsd = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

*.xjb = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

*.wsdl = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

*.properties = svn:mime-type=text/plain;svn:eol-style=native;svn:keywords=Rev Date

.checkstyle = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

.pmd = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

.ruleset = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

*.c = svn:eol-style=native;svn:keywords=Rev Date

*.cpp = svn:eol-style=native;svn:keywords=Rev Date

*.h = svn:eol-style=native;svn:keywords=Rev Date

*.dsp = svn:eol-style=CRLF

*.dsw = svn:eol-style=CRLF

*.sh = svn:eol-style=native;svn:executable

*.bat = svn:eol-style=native

*.pl = svn:eol-style=native

*.py = svn:eol-style=native

*.cmd = svn:eol-style=native

*.txt = svn:eol-style=native;svn:mime-type=text/plain

*.cat = svn:eol-style=native;svn:mime-type=text/plain

*.htm* = svn:eol-style=native;svn:mime-type=text/html;svn:keywords=Rev Date

ChangeLog = svn:eol-style=native;svn:mime-type=text/plain

README* = svn:eol-style=native;svn:mime-type=text/plain

LICENSE* = svn:eol-style=native;svn:mime-type=text/plain

NOTICE* = svn:eol-style=native;svn:mime-type=text/plain

TODO* = svn:eol-style=native;svn:mime-type=text/plain

KEYS* = svn:eol-style=native;svn:mime-type=text/plain

INSTALL* = svn:eol-style=native;svn:mime-type=text/plain

WHATSNEW* = svn:eol-style=native;svn:mime-type=text/plain

NEWS* = svn:eol-style=native;svn:mime-type=text/plain

COPYING = svn:eol-style=native;svn:mime-type=text/plain

*.png = svn:mime-type=image/png

*.jpg = svn:mime-type=image/jpeg

*.gif = svn:mime-type=image/gif

Makefile = svn:eol-style=native

*.css = svn:eol-style=native

*.js = svn:eol-style=native

*.jsx = svn:eol-style=native

*.cxf = svn:mime-type=text/xml;svn:eol-style=native;svn:keywords=Rev Date

----------------------------------------------------------------
使用svn——属性

svn的属性可以说是一个非常好的创意,他是代码非常好的一种补充。
属性是外部不可见的,你可以简单的认为他就是一个文件的一个信息,和文件大小之类的信息是一样的,只不过他是通过svn来管理的。

从我个人的角度,我认为绝大多数的属性是给程序看的用的,因为他们更加的亲和svn的工具。比如我可以给文件添加一个属性叫做License,然后把我期望的属性填充进去。
属性相关的操作有propset,propget,proplist,propdel等。具体命令如下
$svn propset prop_name value
$svn propget prop_name filename
$svn proplist filename
$svn propdel prop_name filename

其中对我们来说有一些实际意义的属性是svn提供的一些特殊属性,这些属性是有特殊的含义的。我认为对我来说最常用的是
svn:keywords 给文件定义一些关键字,比如Author,LastChangedDate等
svn:mime-type 给文件定义mime-type,其中如果是二进制的mime-type则svn会针对文件进行二进制操作
svn:eol-stype 给文件定义如何定义行结束符,是windows形式的或者unix形式的,或者根据系统自动选择,一般都是设置成为自动选择,也就是value是native
svn:externals 这个昨天我介绍过,就是外部定义,请参阅使用svn——外部定义
http://yinwm.cn/blog/2008/01/svn-externals.html
一般对于这些属性的定义,可以使用svn propset,但是对于一些属性,比如svn:keywods, svn:eol-style这些几乎每个文件都要定义的属性,如果一个一个的定义,手就残了。bingo,有人想到了写一个shell脚本,的确是个好主意,但是每次都需要执行,也很烦。svn提供了一个形式,可以让你在对文件进行管理的时候,自动进行属性的添加。也就是修改svn的config文件的 [auto-props]这部分。
svn的config文件请参阅“config”一节才,
http://svndoc.iusesvn.com/svnbook/1.2/svn.advanced.html#svn.advanced.confarea.opts.config
(文件存放的位置是,linux是$HOME/.subversion/config,windows通常放在是c:\documents and settings\%user%\application data\subverion\config)
一般的,我们需要设置的属性,按照这个形式书写
file-pattern = prop-name=value
例如
.* = svn:eol-style=native
这就是说明无论是什么样子的文件名,都设置上svn:eol-style这个属性,属性的值为native。

这几基本上说了一些关于svn属性的东西,具体的文档可以参阅svn的属性章节
http://svndoc.iusesvn.com/svnbook/1.2/svn.advanced.props.html
也许有一些同学发现其实svn:keywords这个东西很值得说,是的,但是之所以我这里不表,是因为更多的我认为他应该属于svn规范的一部分,所以稍后再说。如果有同学想看看,那么去这个地方了解一下 http://svndoc.iusesvn.com/svnbook/1.2/svn.advanced.props.html#svn.advanced.props.special.keywords也好。

----------------------------------------------------------------------
总结:Svn自动属性设置
问题提出:
    我们在用svn管理代码时候,有时候我们需要在java代码里添加上该文件的版本信息、最后修改日期、最后修改用户等信息。
而这个又不能每次把文件提交到svn上时,更改这些信息。
解决方法:
    幸好svn有一个自动属性的功能,即给给该文件添加一些属性,比如svn:keywords,添加该文件的关键字,这样在该文件内容里就会识别该关键字,而把关键字的地方替换成svn服务器上的相应属性。
比如:

    我现在在svn控制目录下创建一个文件”自动属性.txt"
往里面添加内容为:
txt代码
$Id$  
$Date$  

把该文件添加到svn版本控制中(add,commit),此时txt中的内容还是:
txt代码
$Id$  
$Date$ 


点击自动属性.txt的属性 ,弹出属性的对话框。在subversion选项卡上选择properties,添加一个svn:keywords属性:LastChangedDate LastChangedRevision
Id Date  各属性之间用空格隔开。
把“自动属性.txt”再commit到服务上去,这时“自动属性.txt”的文件内容就添加了svn服务器上的相应属性(注“自动属性.txt”的的编码必须为utf-8,否则中文会出现乱码):
txt代码

$Id: 自动属性.txt 2543 2007-12-28 06:52:06Z chen_xk $  
$Date: 2007-12-28 14:52:06 +0800 (星期五, 28 十二月 2007) $  

但是这样必须每次要往svn服务器添加一个文件时,都要设置该文件的属性,有没有一个全部设置的方法,后来终于发现在一个方法: 修改C:\Documents and Settings\Administrator\Application Data\Subversion\config文件,Administrator是windows用户名,添加(注:#表示注释,该把#去掉):
txt代码
enable-auto-props = yes  
[auto-props]  
*.java = svn:keywords=Date Rev Id  
*.txt = svn:keywords=LastChangedDate LastChangedRevision  

这样就大功告成。




你可能感兴趣的:(xml,windows,SVN,FreeBSD,subversion)