2007年6月1日 星期五

svn:externals

svn:externals屬性保存了指導Subversion從一個或多個取出的工作拷貝移出目錄的指示。

外部定義

有時候創建一個由多個不同檢出得到的工作拷貝是非常有用的,舉個例子,你或許希望不同的子目錄來自不同的版本庫位置,或者是不同的版本庫。你可以手工設置這樣一個工作拷貝—使用svn checkout來創建這種你需要的嵌套的工作拷貝結構。但是如果這個結構對所有的用戶是很重要的,每個用戶需要執行同樣的檢出操作。

很幸運,Subversion提供了外部定義的支援,一個外部定義是一個本地路經到URL的影射—也有可能一個特定的修訂版本—一些版本化的資源。在Subversion你可以使用svn:externals屬性來定義外部定義,你可以用svn propsetsvn propedit(見“爲什麽需要屬性?”一節)創建和修改這個屬性。它可以設置到任何版本化的路經,它的值是一個多行的子目錄和完全有效的Subversion版本庫URL的列表(相對於設置屬性的版本化目錄)。

$ svn propget svn:externals calc

third-party/sounds http://sounds.red-bean.com/repos

third-party/skins http://skins.red-bean.com/repositories/skinproj

third-party/skins/toolkit -r21 http://svn.red-bean.com/repos/skin-maker

svn:externals的方便之處是這個屬性設置到版本化的路徑後,任何人可以從那個目錄取出一個工作拷貝,同樣得到外部定義的好處。換句話說,一旦一個人努力來定義這些嵌套的工作拷貝檢出,其他任何人不需要再麻煩了—Subversion會在原先的工作拷貝檢出之後,也會檢出外部工作拷貝。

注意前一個外部定義實例,當有人取出了一個calc目錄的工作拷貝,Subversion會繼續來取出外部定義的專案。

$ svn checkout http://svn.example.com/repos/calc

A calc

A calc/Makefile

A calc/integer.c

A calc/button.c

Checked out revision 148.

Fetching external item into calc/third-party/sounds

A calc/third-party/sounds/ding.ogg

A calc/third-party/sounds/dong.ogg

A calc/third-party/sounds/clang.ogg

A calc/third-party/sounds/bang.ogg

A calc/third-party/sounds/twang.ogg

Checked out revision 14.

Fetching external item into calc/third-party/skins

如果你希望修改外部定義,你可以使用普通的屬性修改子命令,當你提交一個svn:externals屬性修改後,當你運行svn update時,Subversion會根據修改的外部定義同步檢出的專案,同樣的事情也會發生在別人更新他們的工作拷貝接受你的外部定義修改時。

svn status命令也認識外部定義,會爲外部定義的子目錄顯示X狀態碼,然後叠代這些子目錄來顯示外部專案的子目錄狀態資訊。

提示

你一定要要考慮在所有的外部定義中使用明確的修訂版本,這樣做意味著你已經決定了何時拖出外部資訊不同的快照,和精確的拖出哪個快照。除了不會受到第三方版本庫的意外修改的影響以外,當你的工作拷貝回溯到以前的版本庫時,使用明確的修訂版本號會讓外部定義回到以前的那個修訂版本,也意味著外部定義的工作拷貝更新會匹配以前修訂版本的樣子。對於軟體專案,這可能是編譯複雜代碼基的老快照成功和失敗的區別。

Subversion目前對外部定義的支援可能會引起誤導,首先,一個外部定義只可以指向目錄,而不是文件。第二,外部定義不可以指向相對路徑(如../../skins/myskin)。第三,通過外部定義創建的工作拷貝與主工作拷貝沒有連接,所以舉個例子,如果你希望提交一個或多個外部定義的拷貝,你必須在這些工作拷貝顯示的運行svn commit—對主工作拷貝的提交不會叠代到外部定義的部分。

另外,因爲定義本身使用絕對路徑,移動和拷貝路徑他們附著的路徑不會影響他們作爲外部的檢出(儘管相對的本地目標子目錄會這樣,當然,根據重命名的目錄)。這看起來有些迷惑—甚至讓人沮喪—在特定情形。舉個例子,如果你在/trunk開發線對一個目錄使用外部定義,指向同一條線上的其他區域,然後使用svn copy把分支開發線拷貝到/branches/my-branch這個新位置,這個專案新分支的外部定義仍然指向/trunk版本化資源。另外,需要意識到如果你需要一個重新規劃你的工作拷貝的父目錄(使用svn switch --relocate),外部定義不會重新選擇父目錄。

最後,你或許經常希望svn子命令不會識別或其他作爲外部定義處理的結果的外部工作拷貝上的操作,在這種情況下,你可以對子命令使用--ignore-externals選項。

沒有留言: