キーワード置換

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$.

すべてのキーワードは大文字小文字の区別がありファイル中での 目印になります: キーワードが展開されるように大文字小文字を正しく 使う必要があります。 svn:keywords 属性の値 についても大文字小文字の区別を考慮すべきです — ある種の キーワードは大文字小文字を区別せずに解釈されますがこの仕様は 過去のものです。

Subversion は、置換可能なキーワードのリストを定義しています。 そのリストは、以下の五つのキーワードで、そのいくつかについては 別名を使うこともできます:

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

このキーワードは、ファイルがリポジトリで変更された最後のリビジョン をあらわし、$Revision: 144 $のようなものです。これは LastChangedRevisionまたは Revと省略することもできます。

Author

このキーワードはリポジトリ中のこのファイルを最後に変更したユーザ をあらわし、$Author: harry $のようなものです。これは LastChangedByと省略することもできます。

HeadURL

このキーワードはリポジトリ中のファイルの最後のバージョン に対する完全なURLをあらわし、 $HeadURL: http://svn.collab.net/repos/trunk/README $ のようなものです。これは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.

キーワードアンカーテキストをファイルに付け加えただけでは何も 起きません。明示的に要求しなければ Subversion は 決してテキスト置換をやろうとはしません。ようは、 キーワードのそのものの使い方についてのドキュメントを [14] 書いているときに、そのすばらしい例自身がSubversionに よって置換されてほしくはないでしょう。

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キーワードを含んでいたとします。私たちはこの キーワードをまだ属性値として設定していません。Subversionはファイル に存在しないキーワードを置換する要求を無視しますし、 svn:keywords 属性値に存在しないキーワードを 置換することもありません。

この属性の変更をコミットした直後、Subversionは作業ファイルを、新しい 置換テキストで更新します。キーワードアンカー $LastChangedDate$を見るかわりに、置換結果を 見ることになるでしょう。この結果はキーワードの名前を含み、ドル記号 文字($) でくくられています。そして述べたように、 Rev は設定していないので、置換されませんでした。

svn:keywords 属性を「Date Author」 に設定してもキーワードの目印は$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ファイルのキーワードはそのファイルを コミットした一番最後の状態を反映する情報で置換されるでしょう。

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).

警告

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.



[14] … あるいは、その本の一節を…