### Peg和實施修訂版本
文件和目錄的拷貝、移動和改名能力可以讓我們可以刪除一個對象,然后在同樣的路徑添加一個新的―這是我們在電腦上對文件和目錄經常作的操作,我們認為這些操作都是理所當然的。Subversion很樂意你認為這些操作已經賦予給你,Subversion的文件管理操作是這樣的解放,提供了幾乎和普通文件一樣的操作版本化文件的靈活性,但是靈活意味著在整個版本庫的生命周期中,一個給定的版本化的資源可能會出現在許多不同的路徑,一個給定的路徑會展示給我們許多完全不同的版本化資源。
Subversion可以非常聰明的注意到一個對象的版本歷史變化包括一個“地址改變”,舉個例子,如果你詢問一個曾經上周改過名的文件的所有的日志信息,Subversion會很高興提供所有的日志―重命名發生的修訂版本,外加相關版本之前和之后的修訂版本日志,所以大多數時間里,你不需要考慮這些事情,但是偶爾,Subversion會需要你的幫助來清除混淆。
這個最簡單的例子發生在當一個目錄或者文件從版本控制中刪除時,然后一個新的同樣名字目錄或者文件添加到版本控制,清除了你刪除的東西,然后你添加的不是同樣的東西,它們僅僅是有同樣的路徑,我們會把它叫做`/trunk/object`。什么,這意味著詢問Subversion來查看`/trunk/object`的歷史?你是詢問當前這個位置的東西還是你在這個位置刪除的那個對象?你是希望詢問對這個對象的所有操作還是這個路徑的所有對象?很明顯,Subversion需要線索知道你真實的想法。
由于移動,版本化資源歷史會變得非常扭曲。舉個例子,你會有一個目錄叫做`concept`,保存了一些你用來試驗的初生的軟件項目,最終,這個項目變得足夠成熟,說明這個注意確實需要一些翅膀了,所以你決定給這個項目一個名字。 [[32](#)] 假定你叫你的軟件為Frabnaggilywort,此刻,有必要把你的目錄命名為反映項目名稱的名字,所以`concept`改名為`frabnaggilywort`。生活還在繼續,Frabnaggilywort發布了1.0版本,并且被許多希望改進他們生活的分散用戶天天使用。
這是一個美好的故事,但是沒有在這里結束,作為主辦人,你一定想到了另一件事,所以你創建了一個目錄叫做`concept`,周期重新開始。實際上,這個循環在幾年里開始了多次,每一個想法從使用舊的`concept`目錄開始,然后有時在想法成熟之后重新命名,有時你放棄了這個注意而刪除了這個目錄。或者更加變態一點,或許你把`concept`改成其他名字之后又因為一些原因重新改回`concept`。
當這樣的情景發生時,指導Subversion工作在重新使用的路徑上的嘗試就像指導一個芝加哥西郊的乘客駕車到東面的羅斯福路并且左轉到主大道。僅僅20分鐘,你可以穿過惠頓、格倫埃林何朗伯德的“主大道”,但是它們不是一樣的街道,我們的乘客―和我們的Subversion―需要更多的細節來做正確的事情。
在1.1版本,Subversion提供了一種方法來說明你所指是哪一個街道,叫做*peg修訂版本*,這是一個提供給Subversion的一個區別一個獨立歷史線路的單獨目的修訂版本,因為一個版本化的文件會在任何時間占用某個路徑―路徑和peg修訂版本的合并是可以指定一個歷史的特定線路。Peg修訂版本可以在Subversion命令行客戶端中用*at語法*指定,之所以使用這個名稱是因為會在關聯的修訂版本的路徑后面追加一個“at符號”(`@`)。
但是我們在本書多次提到的`--revision (-r)`到底是什么?修訂版本(或者是修訂版本集)叫做*實施的修訂版本*(或者叫做*實施的修訂版本范圍*),一旦一個特定歷史線路通過一個路徑和peg修訂版本指定,Subversion會使用實施的修訂版本執行要求的操作。類似的,為了指出這個到我們芝加哥的道路,如果我們被告知到惠頓主大道606號, [[33](#)] 我們可以把“主大道”看作路徑,把“惠頓”當作我們的peg修訂版本。這兩段信息確認了我們可以旅行(主大道的北方或南方)的唯一路徑,也會保持我們不會在前前后后尋找目標時走到錯誤的主大道。現在我們把“606 N.”作為我們實施的修訂版本,我們*精確的*知道到哪里。
當使用peg和實施修訂版本來查找我們需要工作文件時,Subversion會執行一個很直接的算法。首先,找到與peg修訂版本相關的路徑坐落于版本庫的那個修訂版本,Subversion開始從那里開始向后查詢這個對象的歷史前輩。每個前輩表示這個對象的以前的一個版本,每一個版本的對象都保存了自己被創建的修訂版本和路徑,所以通過前輩集,Subversion可以注意到哪個版本是這個實施修訂版本最年輕的版本,如果是,可以將實施修訂版本影射到前輩創建的路徑/創建修訂版本對。算法在所有的實施修訂版本影射到真實的對象位置后,或者是沒有更多的前輩時完成,就是任何未影射的實施修訂版本已經標記為不符合操作的對象。
也就是說很久以前我們創建了我們的版本庫,在修訂版本1添加我們第一個`concept`目錄,并且在這個目錄增加一個`IDEA`文件與concept相關,在幾個修訂版本之后,真實的代碼被添加和修改,我們在修訂版本20,修改這個目錄為`frabnaggilywort`。通過修訂版本27,我們有了一個新的概念,所以一個新的`concept`目錄用來保存這些東西,一個新的`IDEA`文件來描述這個概念,然后經過5年20000個修訂版本,就像他們都有一個非常浪漫的歷史。
現在,一年之后,我們想知道`IDEA`在修訂版本1時是什么樣子,但是Subversion需要知道我們是想詢問*當前*文件在修訂版本1時的樣子,還是希望知道`concepts/IDEA`在修訂版本1時的那個文件?確定這些問題有不同的答案,并且因為peg修訂版本,你可以用兩種方式詢問。為了知道當前的`IDEA`文件在舊版本1的樣子,我們可以運行:
~~~
$ svn cat -r 1 concept/IDEA
subversion/libsvn_client/ra.c:775: (apr_err=20014)
svn: Unable to find repository location for 'concept/IDEA' in revision 1
~~~
當然,在這個例子里,當前的`IDEA`文件在修訂版本1中并不存在,所以Subversion給出一個錯誤,這個上面的命令是長的peg修訂版本命令一個縮寫,擴展的寫法是:
~~~
$ svn cat -r 1 concept/IDEA@BASE
subversion/libsvn_client/ra.c:775: (apr_err=20014)
svn: Unable to find repository location for 'concept/IDEA' in revision 1
~~~
當執行時會有預料中的結果,當應用到工作拷貝路徑時,Peg修訂版本通常缺省值是`BASE`(在當前工作拷貝現在的修訂版本),當應用到URL時,缺省值是`HEAD`。
然后讓我們詢問另一個問題―在修訂版本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.
~~~
這看起來是正確的輸出,這些文本甚至提到“frabbing naggily worts”,所以這就是現在叫做Frabnaggilywort項目的那個文件,實際上,我們可以使用顯示的peg修訂版本和實施修訂版本的組合核實這一點。我們知道在`HEAD`,Frabnaggilywort項目坐落在`frabnaggilywort`目錄,所以我們指定我們希望看到`HEAD`的`frabnaggilywort/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清除混淆的額外提示。
“你不是被期望去命名它,一旦你取了名字,你開始與之聯系在一起。” ― Mike Wazowski
伊利諾伊州惠頓主大道606號市惠頓離市中心,讓它作為―“歷史中心”?看起來是恰當的…。
- 第1章介紹
- Subversion的歷史
- Subversion的特性
- Subversion的架構
- 安裝Subversion
- Subversion的組件
- 快速入門
- 第2章基本概念
- 版本模型
- Subversion實戰
- 摘要
- 第3章指導教程
- 導入
- 修訂版本: 號碼、關鍵字和日期,噢,我的!
- 初始化的Checkout
- 基本的工作周期
- 檢驗歷史
- 其他有用的命令
- 摘要
- 第4章分支與合并
- 使用分支
- 在分支間拷貝修改
- 常見用例
- 轉換工作拷貝
- 標簽
- 分支維護
- 摘要
- 第5章版本庫管理
- 版本庫的創建和配置
- 版本庫維護
- 添加項目
- 摘要
- 第6章配置服務器
- 網絡模型
- svnserve,一個自定義的服務器
- httpd,Apache的HTTP服務器
- 支持多種版本庫訪問方法
- 第7章高級主題
- 屬性
- Peg和實施修訂版本
- 外部定義
- 賣主分支
- 本地化
- Subversion版本庫URL
- 第8章開發者信息
- 使用API
- 進入工作拷貝的管理區
- WebDAV
- 使用內存池編程
- 為Subversion做貢獻
- 第9章Subversion完全參考
- svn add
- svn blame
- svn cat
- svn checkout
- svn cleanup
- svn commit
- svn copy
- svn delete
- svn diff
- svn export
- svn help
- svn import
- svn info
- svn list
- svn log
- svn merge
- svn mkdir
- svn move
- svn propdel
- svn propedit
- svn propget
- svn proplist
- svn propset
- svn resolved
- svn revert
- svn status
- svn switch
- svn update
- svnadmin
- svnadmin create
- svnadmin deltify
- svnadmin dump
- svnadmin help
- svnadmin hotcopy
- svnadmin list-dblogs
- svnadmin list-unused-dblogs
- svnadmin load
- svnadmin lstxns
- svnadmin recover
- svnadmin rmtxns
- svnadmin setlog
- svnadmin verify
- svnlook
- svnlook author
- svnlook cat
- svnlook changed
- svnlook date
- svnlook diff
- svnlook dirs-changed
- svnlook help
- svnlook history
- svnlook info
- svnlook log
- svnlook propget
- svnlook proplist
- svnlook tree
- svnlook uuid
- svnlook youngest
- svnserve
- svnversion
- mod_dav_svn Configuration Directives
- 附錄A.Subversion對于CVS用戶
- 目錄的版本
- 更多離線操作
- 區分狀態和更新
- 分支和標簽
- 元數據屬性
- 沖突解決
- 二進制文件和轉化
- 版本化的模塊
- 認證
- 轉化CVS版本庫到Subversion
- 附錄C.WebDAV和自動版本化
- 自動版本化交互性
- Subversion和DeltaV
- 術語表