Subversion具備新增關鍵字的能力—一些有用的,關於版本化的文件動態訊息的片斷—不必直接新增到文件本身。關鍵字通常會用來描述文件最後一次修改的一些訊息,因為這些訊息每次都有改變,更重要的一點,這是在文件修改之後,除了版本控制系統,對於任何企圖保持資料最新的過程都是一場混亂,作為人類作者,訊息變得陳舊是不可避免的。
舉個例子,你有一個文件希望顯示最後修改的日期,你需要麻煩每個作者提交之前做這件事情,也要修改文件的一部分來描述何時作的修改,但是遲早會有人忘記做這件事,不選擇簡單的告訴Subversion來執行替換LastChangedDate關鍵字的操作,你通過在目標位置放置一個keyword anchor來控制關鍵字插入的位置,這個anchor只是一個格式為$KeywordName$字元串。
所有作為anchor出現在文件裡的關鍵字是大小寫敏感的:為了關鍵字的擴展,你必須使用正確的大寫,你必須考慮svn:keywords的屬性值也是大小寫敏感—特定的關鍵字名會忽略大小寫,但是這個特性已經被廢棄了。
Subversion定義了用來替換的關鍵字列表,這個列表保存了如下五個關鍵字,有一些也包括了可用的別名:
Date
這個關鍵字保存了文件最後一次在版本庫修改的日期,看起來類似於$Date: 2008-11-28 17:00:49 +0800 (週五, 28 十一月 2008) $,它也可以用LastChangedDate來指定。
Revision
這個關鍵字描述了這個文件最後一次修改的修訂版本,看起來像$Revision: 1042 $,也可以通過LastChangedRevision或者Rev引用。
Author
這個關鍵字描述了最後一個修改這個文件的用戶,看起來類似$Author: dongsheng.song $,也可以用LastChangedBy來指定。
HeadURL
這個關鍵字描述了這個文件在版本庫最新版本的完全URL,看起來類似$HeadURL: http://i18n-zh.googlecode.com/svn/www/svnbook-1.4/svn.advanced.props.special.keywords.html $,可以縮寫為URL。
Id
這個關鍵字是其他關鍵字一個壓縮組合,它看起來就像$Id: svn.advanced.props.special.keywords.html 1042 2008-11-28 09:00:49Z dongsheng.song $,可以解釋為文件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: 2008-11-28 17:00:49 +0800 (週五, 28 十一月 2008) $ $Rev: 1042 $ 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: 2008-11-28 17:00:49 +0800 (週五, 28 十一月 2008) $的關鍵字anchor,你會看到替換的結果,這個結果也保存了關鍵字的名字,與美元符號($)綁定在一起,而且我們預測的,Rev關鍵字不會被替換,因為我們沒有要求這樣做。
注意我們設定svn:keywords屬性為「Date Author」,關鍵字anchor使用別名$LastChangedDate: 2008-11-28 17:00:49 +0800 (週五, 28 十一月 2008) $並且正確的擴展。
Here is the latest report from the front lines. $LastChangedDate: 2008-11-28 17:00:49 +0800 (週五, 28 十一月 2008) $ $Rev: 1042 $ Cumulus clouds are appearing more frequently as summer approaches.
如果有其他人提交了weather.txt的修改,你的此文件的拷貝還會顯示同樣的替換關鍵字值—直到你更新你的工作副本,此時你的weather.txt重的關鍵字將會被替換來反映最新的提交訊息。
Subversion 1.2引入了另一種關鍵字的語法,提供了額外和有用的,儘管是非典型的功能。你現在可以告訴Subversion為替代的關鍵字維護一個固定長度(從消耗字節的觀點),通過在關鍵字名後使用雙冒號(::),然後緊跟一組空格,你就定義了固定寬度。當Subversion使用替代值代替你的關鍵字,只會替換這些空白字元,保持關鍵字字段長度保持不變,如果替代值比定義的字段短,會有替代字段後保留空格;如果替代值太長,就會在最後的美元符號終止符前用井號(#)截斷。
例如,你有一篇文件,其中一段是一些反映Subversion關鍵字的表格資料,使用原始的Subversion關鍵字替換語法,你的文件或許像這樣:
$Rev: 1042 $: Revision of last commit $Author: dongsheng.song $: Author of last commit $Date: 2008-11-28 17:00:49 +0800 (週五, 28 十一月 2008) $: Date of last commit
現在,表格看起來佷漂亮,但是當你提交文件(當然,關鍵字替換功能已打開),你會看到:
$Rev: 1042 $: Revision of last commit $Author: dongsheng.song $: Author of last commit $Date: 2008-11-28 17:00:49 +0800 (週五, 28 十一月 2008) $: Date of last commit
結果並不漂亮,你可能會嘗試重新調整文件使之更像一個列表。只有關鍵字的長度是相同的時候才能保證保持樣式,如果進入另一個修訂版本(如從99到100),或者是另一個有較長用戶名的人提交了文件,表格又會變形。然而,如果你使用Subversion 1.2,你可以使用新的固定長度的關鍵字語法,定義合適的字段寬度,然後你的文件可能如此:
$Rev:: 1042 $: Revision of last commit $Author:: dongsheng.#$: Author of last commit $Date:: 2008-11-28 1#$: Date of last commit
你提交這個文件的修改,這一次Subversion注意到了新的固定長度的關鍵字語法,根據你在雙冒號之間指定的空格長度調整格式,並且緊跟一個美元符號。經過替換,字段的長度沒有發生變化—Rev和Author多了一些空格,而較長的Date字段被一個分號截斷:
$Rev:: 1042 $: Revision of last commit $Author:: dongsheng.#$: Author of last commit $Date:: 2008-11-28 1#$: Date of last commit
固定長度關鍵字在執行複雜文件格式的替換中非常易用,也可以處理那些很難通過其他程序(例如Microsoft Office文件)進行修改的文件。
需要意識到,因為關鍵字字段的長度是以字節為單位,可能會破壞多字節值,例如一個用戶名包含多字節的UTF-8字元,可能會遭遇從某個字元中間截斷的情況,從字節角度看僅僅是一種截斷,但是從UTF-8字元串角度看可能是錯誤和曲解的,當載入文件時,破壞的UTF-8文字可能導致整個文件的破壞,整個文件無法操作。所以,當限制關鍵字為固定大小時,需要選擇一個可以擴展的大小。