Peg 和實施修訂版本

文件和目錄的拷貝、改名和移動能力使你可以建立一個項目,然後刪除它,然後在同一個位置新增一個新的—這是在我們的計算機中經常發生的操作,而你的版本控制系統不應該成為你這樣操作的障礙。Subversion的文件管理操作是這樣的開放,提供了幾乎和普通文件一樣的操作版本化文件的靈活性,但是靈活意味著在整個版本庫的生命週期中,一個給定的版本化的資源可能會出現在許多不同的路徑,一個給定的路徑會展示給我們許多完全不同的版本化資源。當然這些功能也增加了你與這些路徑和資源交互的難度。

Subversion可以非常聰明的注意到一個對象的包括一個「地址改變」歷史變化,舉個例子,如果你詢問一個曾經上周改過名的文件的所有的日誌訊息,Subversion會很高興提供所有的日誌—重命名發生的修訂版本,外加相關版本之前和之後的修訂版本日誌,所以大多數時間裡,你不需要考慮這些事情,但是偶爾,Subversion會需要你的幫助來清除混淆。

這個最簡單的例子發生在當一個目錄或者文件從版本控制中刪除時,然後一個新的同樣名字目錄或者文件新增到版本控制,顯然你刪除的和你後來新增的不是同樣的東西,它們僅僅是有同樣的路徑,例如/trunk/object。什麼,這意味著詢問Subversion來查看/trunk/object的歷史?你是詢問當前這個位置的東西還是你在這個位置刪除的那個對象?你是希望詢問對這個對象的所有操作還是這個路徑的所有對象?很明顯,Subversion需要線索知道你真實的想法。

由於移動,版本化對象的歷史會變得非常扭曲。舉個例子,你會有一個目錄叫做concept,保存了一些你用來試驗的初生的軟體項目,最終,這個項目變得足夠成熟,說明這個注意確實需要一些翅膀了,所以你決定給這個項目一個名字。 [18]假定你叫你的軟體為Frabnaggilywort,此刻,把你的目錄命名為反映項目名稱的名字是有意義的,所以concept改名為frabnaggilywort。生活還在繼續,Frabnaggilywort發佈了1.0版本,並且被許多希望改進他們生活的分散用戶天天使用。

這是一個美好的故事,但是沒有在這裡結束,作為主辦人,你一定想到了另一件事,所以你建立了一個目錄叫做concept,週期重新開始。實際上,這個循環在幾年裡開始了多次,每一個想法從使用舊的concept目錄開始,然後有時在想法成熟之後重新命名,有時你放棄了這個注意而刪除了這個目錄。或者更加變態一點,或許你把concept改成其他名字之後又因為一些原因重新改回concept

當這樣的情景發生時,指導Subversion工作在重新使用的路徑上的嘗試就像指導一個芝加哥西郊的乘客駕車到東面的羅斯福路並且左轉到主大道。僅僅20分鐘,你可以穿過惠頓、格倫埃林何朗伯德的「主大道」,但是它們不是一樣的街道,我們的乘客—和我們的Subversion—需要更多的細節來做正確的事情。

在1.1版本,Subversion提供了一種方法來說明你所指是哪一個街道,叫做peg修訂版本,通過這個修訂版本我們可以唯一確定一條歷史線路,因為一個版本化的文件會在任何時間佔用某個路徑—路徑和peg修訂版本的合併是可以指定一個歷史的特定線路。Peg修訂版本可以在Subversion指令列客戶端中用at語法指定,之所以使用這個名稱是因為會在關聯的修訂版本的路徑後面追加一個「at符號」(@)。

但是我們在本書多次提到的--revision (-r)到底是什麼?修訂版本(或者是修訂版本集)叫做實施的修訂版本(或者叫做實施的修訂版本範圍),一旦一個特定歷史線路通過一個路徑和peg修訂版本指定,Subversion會使用實施的修訂版本執行要求的操作。類似的,為了指出這個到我們芝加哥的道路,如果我們被告知到惠頓主大道606號, [19] 我們可以把「主大道」看作路徑,把「惠頓」當作我們的peg修訂版本。這兩段訊息確認了我們可以旅行(主大道的北方或南方)的唯一路徑,也會保持我們不會在前前後後尋找目標時走到錯誤的主大道。現在我們把「606 N.」作為我們實施的修訂版本,我們精確的知道到哪裡。

也就是說很久以前我們建立了我們的版本庫,在修訂版本1新增我們第一個concept目錄,並且在這個目錄增加一個IDEA文件與concept相關,在幾個修訂版本之後,真實的代碼被新增和修改,我們在修訂版本20,修改這個目錄為frabnaggilywort。通過修訂版本27,我們有了一個新的概念,所以一個新的concept目錄用來保存這些東西,一個新的IDEA文件來描述這個概念,然後經過5年20000個修訂版本,就像他們都有一個非常浪漫的歷史。

現在,一年之後,我們想知道IDEA在修訂版本1時是什麼樣子,但是Subversion需要知道我們是想詢問當前文件在修訂版本1時的樣子,還是希望知道concepts/IDEA在修訂版本1時的那個文件?確定這些問題有不同的答案,並且因為peg修訂版本,你可以用兩種方式詢問。為了知道當前的IDEA文件在舊版本的樣子,我們可以運行:

$ svn cat -r 1 concept/IDEA 
svn: Unable to find repository location for 'concept/IDEA' in revision 1

當然,在這個例子裡,當前的IDEA文件在修訂版本1中並不存在,所以Subversion給出一個錯誤,這個上面的命令是長的peg修訂版本命令一個縮寫,擴展的寫法是:

$ svn cat -r 1 concept/IDEA@BASE
svn: Unable to find repository location for 'concept/IDEA' in revision 1

當執行時,它包含期望的結果。

如果工作副本路徑或URL中確實有一個at記號,peg修訂版本語法是否會導致問題?深刻理解的讀者可能會產生這樣的疑問。畢竟,svn是如何知道news@11是我的目錄樹中的一個目錄,還是修訂版本11的news文件?幸好,svn會一直假定後者。你只需要在路徑最後新增一個at符號,例如news@11@svn只關心最後一個at標記,如果遺漏了最後的修訂版本號,不會認為不合法。這個法則甚至可以應用到以at結尾的路徑—你可以使用filename@@來引用filename@

然後讓我們詢問另一個問題—在修訂版本1 ,佔據concepts/IDEA路徑的文件的內容到底是什麼?我們會使用一個明確的peg修訂版本來幫助我們完成。

$ svn cat concept/IDEA@1
The idea behind this project is to come up with a piece of software
that can frab a naggily wort.  Frabbing naggily worts is tricky
business, and doing it incorrectly can have serious ramifications, so
we need to employ over-the-top input validation and data verification
mechanisms.

注意我們這一次沒有提供操作修訂版本,那是因為如果沒有指定操作修訂版本,Subversion假定預設的操作修訂版本是peg修訂版本。

正像你看到的,這看起來是正確的輸出,這些文字甚至提到「frabbing naggily worts」,所以這就是現在叫做Frabnaggilywort項目的那個文件,實際上,我們可以使用顯示的peg修訂版本和實施修訂版本的組合核實這一點。我們知道在HEAD,Frabnaggilywort項目坐落在frabnaggilywort目錄,所以我們指定我們希望看到HEADfrabnaggilywort/IDEA路經在歷史上的修訂版本1的內容。

$ svn cat -r 1 frabnaggilywort/IDEA@HEAD
The idea behind this project is to come up with a piece of software
that can frab a naggily wort.  Frabbing naggily worts is tricky
business, and doing it incorrectly can have serious ramifications, so
we need to employ over-the-top input validation and data verification
mechanisms.

而且peg修訂版本和實施修訂版本也不需要這樣瑣碎,舉個例子,我們的frabnaggilywort已經在HEAD刪除,但我們知道在修訂版本20它是存在的,我們希望知道IDEA從修訂版本4到10的區別,我們可以使用peg修訂版本20和IDEA文件的修訂版本20的URL的組合,然後使用4到10作為我們的實施修訂版本範圍。

$ svn diff -r 4:10 http://svn.red-bean.com/projects/frabnaggilywort/IDEA@20
Index: frabnaggilywort/IDEA
===================================================================
--- frabnaggilywort/IDEA	(revision 4)
+++ frabnaggilywort/IDEA	(revision 10)
@@ -1,5 +1,5 @@
-The idea behind this project is to come up with a piece of software
-that can frab a naggily wort.  Frabbing naggily worts is tricky
-business, and doing it incorrectly can have serious ramifications, so
-we need to employ over-the-top input validation and data verification
-mechanisms.
+The idea behind this project is to come up with a piece of
+client-server software that can remotely frab a naggily wort.
+Frabbing naggily worts is tricky business, and doing it incorrectly
+can have serious ramifications, so we need to employ over-the-top
+input validation and data verification mechanisms.

幸運的是,幾乎所有的人不會面臨如此複雜的情形,但是如果是,記住peg修訂版本是幫助Subversion清除混淆的額外提示。



[18] 你不是被期望去命名它,一旦你取了名字,你開始與之聯繫在一起。」 — Mike Wazowski

[19] 伊利諾伊州惠頓主大道606號市惠頓離市中心,讓它作為—「歷史中心」?看起來是恰當的…。