Subversion 發佈新版本1.5 新特性完全解析

北京時間2008年6月20日凌晨,令人期待的Subversion1.5發佈,Subversion1.5包含了超過所有以前版本的改進。Subversion中文站第一時間爲大家提供了中文版的發佈說明,另外我們還爲大家準備了Subversion1.5專題,給許多特性提供了更深入的討論。還有我們翻譯的《使用Subversion進行版本控制》也已經發布1.4版本,最新的1.5版本也正在翻譯中。

譯者:http://rocksun.cn 原始出處:http://www.subversion.org.cn/?action-viewnews-itemid-42

Subversion 1.5的新東西

Subversion 1.5是以前Subversion發佈版本的超集,可以認爲是當前“最好的”版本。包含所有1.0.x到1.4.x的,以及以前版本沒有的修正和特性。所有的新特性將會寫入Subversion book,見svnbook.red-bean.com

兼容性問題

以前的客戶端和服務器可以直接與1.5的服務器和客戶端交互,然而,如果服務器和客戶端不全是1.5時,一些新的1.5特性(例如合併跟蹤)將會不可用,而另外一些特性如稀疏檢出,在服務器是舊的,客戶端是新的時,可以運行但是效率比較低。

沒有必要轉儲並重新加載版本庫,subversion1.5可以讀取以前創建的版本,升級只需用最新的庫和二進制程序覆蓋原來的程序。

Subversion會維護與先前版本API/ABI的兼容,只會增加新的特性,而不會刪除舊的特性。根據1.0, 1.1, 1.2, 1.3或1.4 的API編寫的程序,可以使用1.5的庫編譯,爲1.5編寫的程序不必爲舊庫編譯或運行。

新特性的兼容性表格

新特性

Minimum Client

Minimum Server

Minimum Repository

Notes

合併跟蹤(基礎)

1.5

1.5

1.5

 

稀疏檢出(通過新的–depth選項)

1.5

any

any

 

交互式的衝突解決

1.5

any

any

 

變更列表支持

1.5

any

any

 

svn:externals的相對URL和peg修訂版本

1.5

any

any

 

對於ra_svn和svnserve的Cyrus SASL支持

any*, 1.5

any*, 1.5

any

*受限,見 SASL 和svn:// 兼容性

通過sharding對於FSFS的大規模開發的支持

any*, 1.5

1.5

1.5

*1.5 file:// 兼容性需要

FSFS優化,通過不變的文件隔離

any*, 1.5

1.5

1.5

*1.5 file:// 兼容性需要

WebDAV的透明通過代理寫

any

1.5*

any

*需要Apache 2.2服務器

copy 和move的改進

1.5

any*, 1.5

any

*受限,見copy 和move的改進

速度改進,取消響應改進

1.5

any

any

 

更簡單的使用試驗ra_serf DAV訪問模塊

1.5

any

any

 
工作拷貝和版本庫格式更改

工作拷貝格式已經升級,這意味着1.4和更老的Subversion客戶端不能與Subversion1.5的工作拷貝上工作,工作拷貝是自動升級的

類似的,版本庫格式也已經改變,意味着直接訪問庫的1.4以及舊的版本的程序如svnserve,mod_dav_svn,svnadmin等不能讀取Subversion1.5的版本庫,但是版本庫是不能自動升級的

工作拷貝升級

警告:如果一個Subversion1.5客戶端遇到了一個1.5以前的工作拷貝,它會在接觸到工作拷貝時自動升級工作拷貝格式,並使舊的Subversion客戶端不能再讀這些工作拷貝了。如果你在機器上使用多個版本的Subversion,請確認你對工作拷貝是用的subversion版本,防止意外升級工作拷貝。(但是這種自動升級行爲不會發生在版本庫上,只發生在工作拷貝。)

如果你意外的將工作拷貝從1.4升級到1.5,並希望降級到1.4,可以使用change-svn-wc-format.py ,詳情看這篇文章,也可以以–help運行來查看使用指導。

版本庫升級

Subversion 1.5服務器可以與1.4和以前的版本庫工作,如果不使用svnadmin upgrade命令,版本庫不會自動升級到1.5。這意味僅僅升級服務器不能直接得到某些特性,你也需要升級版本庫。(我們決定不使用自動升級版本庫是因爲我們不希望subversion1.5偷偷的升級成1.4不可用的版本庫。)

在運行svnadmin upgrade之後,你或許希望對版本庫運行svn-populate-node-origins-index 程序。Subversion1.5爲每個版本庫維護了一個節點起源的索引,爲了得到一些信息,偶爾構建這個索引。但是對於包含許多修訂的老版本庫,最好一次創建這個索引,使用前面說道的工具,而不會因爲自己構建這個索引而影響查詢的性能,更多細節見issue #3024

命令行輸出的變更

儘管我們希望儘可能讓命令行程序的的輸出與以前版本保持兼容,但是還是要添加一些信息,這會破壞一些精確依賴輸出的腳本。不幸的是,我們不能列出1.5輸出的所有改變,但有一條可以確定的是衝突標記的行結束符號會和文件的eol-style匹配。

SASL和svn://的兼容性

所有1.x的客戶端,包含或不包含Cyrus SASL支持的,都可以通過在Cyrus SASL沒有開啓時認證正常。注意CRAM-MD5ANONYMOUS機制是Subversion內置的,所以即使Cyrus SASL插件不在,我們也可以使用。

沒有Cyrus SASL支持的1.x客戶端不能通過開啓Cyrus SASL,允許CRAM-MD5ANONYMOUS機制的1.5+的subversion服務器認證,

包含Cyrus SASL支持的1.5+客戶端可以通過開啓SASL功能的1.5+服務器認證,只要保證服務器支持的某個機制客戶端也支持。

關於Cyrus SASL的更多信息可以看這個部分

自定義revprops現在需要通過pre-commit鉤子的檢驗

Subversion每個修訂版本都有一組關聯的修訂版本屬性;除了標準的日誌信息,作者和日誌,可以設置任意的用戶定義的屬性。這些屬性本身不是版本化的,所以不能恢復修改的內容。因此,如果我們沒有設置pre-revprop-change,我們就不能修改提交修訂版本的revprops。在Subversion1.5之前,我們只能在提交時提供這三個標準的revprops;管理員使用鉤子來控制這三個標準修訂版本屬性的內容,需要在pre-commit和pre-revprop-change檢查,但是對於自定義的屬性,只有pre-revprop-change是相關的。

Subversion1.5添加了svn commit包含–with-revprop選項,允許用戶在提交時爲修訂版本指定屬性,因此在Subversion 1.5允許在沒有pre-revprop-change鉤子時設置修訂版本屬性,pre-commit可以在提交之前檢查事務修訂版本屬性(就像許多服務器已經使用pre-commit來檢查正確格式化的log)。

這意味着如果你以前依賴pre-revprop-change to 鉤子控制對於修訂版本屬性的修改(不僅僅你是跟蹤它們的歷史),那你先現在也需要在pre-commit添加類似的控制。

新特性

合併跟蹤(基礎)(客戶端和服務器)

合併跟蹤的意思是Subversion保持哪些變更從哪裏合併過來,這減輕了維護分支的負擔,也給了用戶一個方式來查詢合併的變更—或需要合併的內容—在不同的開發線上。

Subversion1.5支持的合併跟蹤是“基礎的”:最重要的部分已經實現,但是在我們最初的規格中還有一部分需要去實現(特別是對於reflective merges的正確支持,更好的change-availability reporting和更好的tracking of renamed files),雖然在1.5還要加入一些主要的特性,但我們不希望爲等待某個特性延遲我們的發佈。更多的合併跟蹤改進希望在Subversion1.6或以後的版本出現。

概述

Subversion的合併跟蹤設計爲:

  • 減少分支維護的記錄負擔
  • 防止常見的“重複合併”問題
  • 允許對於變更的cherry-picking

每個變更集都可以通過修訂版本號識別,通過新的svn:mergeinfo屬性在合併的目標存放在合併變更集的信息(通俗來說就是“合併信息(mergeinfo)”),Subversion會自動保持合併信息的爲最新,但是也有辦法手工記錄/消除合併信息,這是因爲總會有些時候人們知道一些Subversion不知道的事情。

用戶界面

從主幹合併分支不再需要指明修訂版本範圍,每當你希望與trunk同步,你可以這樣做:

   $ cd BRANCH_WORKING_COPY
   $ svn merge URL_TO_TRUNK

Subversion能夠計算出從URL_TO_TRUNK有哪些變更沒有合併,並只處理這些變更,當將分支合併回主幹,我們只需要:

   $ cd TRUNK_WORKING_COPY
   $ svn merge --reintegrate URL_TO_BRANCH

下面是所有合併跟蹤相關接口變更的正式描述。

svn merge命令使用兩個新的選項:--record-only--reintegrate。

–record-only選項至於-r結合工作,並且和你所想的一樣:它只是用來將修訂版本標記爲已合併(或未合併的,使用“-”作爲否定語法),而實際上除了合併信息(mergeinfo),什麼也沒有做。例如,當因爲效率某個人手工修改了這個文件而合併了這個其他地方修改的變更時,這非常有效,與其讓讓變更在下次合併時加入進來,從而引起文本衝突,我們不如記錄這個變更已經合併。(細節見Subversion書的merge-tracking requirements, and Blocking Changes 。)

–reintegrate選項在將分支合併回主幹時使用;它會檢查一些防護措施條件並快速有效的進行合併,更多內容見Subversion book的Keeping a branch in sync

新的svn mergeinfo命令可以顯示一個目錄已經接收的變更集,以及哪些變更集還適合接收,Subversion手冊的Mergeinfo and Previews有更多信息。

svn logsvn blame 命令有了新的-g (--use-merge-history) 選項,使之將mergeinfo納入考慮,如果沒有提供這個選項,它們就會參考合併信息。

 

使用-g選項的原因是有時候忽略合併歷史會更好,在blame輸出中,有時候你希望看到合併變更的人物B,而有些時候你希望看到最初作出這些修改人物A;使用-g可以得到後者的信息。在日誌輸出中,你有時候希望看到某一行提交的修訂版本,而有時你希望看到最初的修改做合併修訂版本轉移走了;再次,-g顯示後者的信息(使用”Merged via: “標識,後面是合併發生的修訂版本號碼),見Subversion手冊的Merge-Sensitive Logs and Annotations

合併跟蹤和兼容性

前面已經說了,在隨server升級版本庫以前不支持合併跟蹤。

如果你正在使用svnmerge包裹程序來進行合併,而現在希望使用Subversion1.5本身的合併跟蹤功能功能,你一定要使用svnmerge-migrate-history.py 腳本來轉化svnmerge的自定義屬性爲Subversion使用的svn:mergeinfo屬性。

已知問題

1.5.0的合併跟蹤還有許多已知的問題,我們首先解決了最重要的,下面是:

  • issue #3128: merge --reintegrate 應該更好的處理重命名
  • issue #2897: 對反向合併的更好支持
  • issue #3126: 更好已知變更報告(svn mergeinfo顯示了太少或太多的合適修訂版本)
  • issue #2837: 當執行循環合併時合併跟蹤能起效果
  • issue #3056: 防止以智能方式重複合併
  • issue #2898: 當刪除/添加子時無需處理合並信息
  • issue #3067: 在合併範圍內不存在的樹不應該破壞合併
  • issue #3157: 從路徑的自然歷史合併變更會創建引用自己的合併信息
  • issue #3174: 合併算法需要對重命名的子樹特別關注

(可以看list of all merge-related open issues,儘管很多不是關於合併跟蹤)

Issue #3157可能是會很容易遇到的,所以下面是如何解決這個問題的詳細描述:

合併跟蹤信息現在可以保存在路徑的“本身歷史”中,當從trunk的特定修訂版本x創建了一個分支,然後將分支的所有變更合併回trunk時,如果沒有明確的限制合併範圍並且沒有使用--reintegrate 選項時,後果是,trunk的合併跟蹤信息將會列出x之前的信息。這對以後的合併操作沒有壞處,但是對於trunk上的svn log -g會使用以前修訂版本的合併跟蹤信息(而不只是HEAD)。

注意,這一定不會是一個發佈分支(也叫做“維護分支”)的問題,因爲一個人通常不會將其合併回主幹,相反,推薦的時間是對於進入trunk的新變更使用特性分支,可以在分支的生命週期結尾一次合併到主幹。

一個辦法是在提交合並修訂之前修正合並跟蹤信息,通過恢復“本身歷史”信息:svn merge --record-only -rX:1。另一個方案是完全防止這種情形,通過在第一次就明確的指定合併範圍,例如-rX:HEAD,更多信息可以看這個郵件

當合並一個特性分支,最佳方案是使用--reintegrate選項

深入閱讀

Subversion 1.5合併跟蹤的更多內容可以看:

稀疏檢出(Sparse checkouts)(客戶端和服務器)

許多用戶都有很大的目錄樹,但他們只希望檢出特定的部分。在Subversion以前的版本,checkout -N沒有真的完成這個任務。Subversion 1.5引入了checkout、switchupdate子命令的–depth選項,這個選項替代了-N,允許用戶構建只包含他們需要內容的工作拷貝,而不管其他的東西。

Depth概述

每個目錄現在理解了depth的概念,可以有四種值:emptyfilesimmediatesinfinity,值的定義如下:

  • –depth=empty: 更新不會拉出任何不存在的文件或目錄
  • –depth=files: 更新會拉出所有的文件,但不包括子目錄
  • –depth=immediates: 更新會拉入所有不存在的文件或子目錄;但子目錄的設置爲depth=empty。
  • –depth=infinity: 更新會拉入所有不存在的文件和目錄,子目錄的設置爲depth=infinity,與目前的缺省更新行爲方式相同。

--depth 選項設置depth的值在更新工作拷貝時按照上面說的方式更新

用戶界面

影響的命令:

  • checkout
  • switch
  • update
  • status
  • info

-N選項開始成爲這些子命令的--depth=files選項的一個別名,這改變了現存的-N行爲方式,但是以一種很瑣碎的方式(見下面)。

現在對於不使用--depth-N 的checkout來說和以前一樣。沒有--depth或-N 的switch和update命令現在只和工作拷貝完全的depth-infinity相同,沒有--depth或-N 的switch或update不會改變depth值(例外:在命令行中指定的不存在的目錄會拉入)。

結果是,checkout與checkout --depth=infinity相同,但是switch和updateswitch --depth=infinity和update --depth=infinity不同,前者根據現存的depth值更新,而後者獲取所有的內容。

作爲開始,可以使用--depth=empty--depth=files選項checkout文件,如果需要額外的文件或目錄,可以使用合適的--depth選項的update命令來獲取。除了其他的狀態信息,svn status必須列出目錄周圍的depths。當調用的目錄的depth不是缺省值(depth-infinity)時svn info命令也會列出其depth。

注意: 當前對於稀疏檢出沒有反選的接口—也就是說,在引入到工作拷貝後(儘管有一些相對簡單的方法可以獲取此目標),沒有命令可以取消選擇或“摺疊”子目錄,詳細信息見issue #2843

與以前服務器的兼容性

–depth特性顯然需要客戶端是1.5以上的,也需要1.5以上的服務器才能最有效的工作,然而,客戶端仍然需要在1.4.x服務器時工作正常;只是有較差的效率。

這是因爲以前的服務器不會理解—因而會忽略—不會清楚客戶端說的“depth”的含義。所以當客戶端請求比depth-infinity更淺的depth,以前的服務器會返回比客戶端需要更多的數據,然而Subversion1.5+的客戶端知道是與舊的服務器通話,並會過濾這些多餘的數據,因此,操作會更長一些,因爲服務器發送了許多客戶端忽略的數據,但是最終在客戶端產生的數據相同。(注意舊的服務器理解網絡協議的recurse,而1.5+客戶端根據depth發送標記;這減輕了額外的網絡懲罰。

進一步閱讀
交互式衝突解決(客戶端)

update/switch/merge 子命令的操作中,現在衝突解決是使用交互式的命令行客戶端完成,客戶端庫提供了一個callback函數,所以其他客戶端也能以同樣的方式工作。

下面是使用命令行客戶端例子:

   $ svn up
   U    contrib/client-side/svnmerge/svnmerge_test.py
   Conflict discovered in 'contrib/client-side/svnmerge/svnmerge.py'.
   Select: (p) postpone, (df) diff-full, (e) edit,
           (s) show all options: s
     (p)  postpone    - mark the conflict to be resolved later
     (df) diff-full   - show all changes made to merged file
     (e)  edit        - change merged file in an editor
     (r)  resolved    - accept merged version of file
     (mf) mine-full   - accept my version of entire file (ignore their changes)
     (tf) theirs-full - accept their version of entire file (lose my changes)
     (l)  launch      - launch external tool to resolve conflict
     (s)  show all    - show this list

   Select: (p) postpone, (df) diff-full, (e) edit,
           (s) show all options: tf
   G    contrib/client-side/svnmerge/svnmerge.py
   Updated to revision 25685.
   $ 

這個特性可以使用–non-interactive選擇關閉,或者通過設置運行配置文件中的“[miscellany] interactive-conflicts = no”永久關閉。

交互式衝突解決的API通過一個callback函數公開,並有如下數據類型:

  • svn_wc_conflict_resolver_func_t,  callback API本身
  • svn_wc_conflict_description_t,  傳遞給callback的衝突描述
  • svn_wc_conflict_action_t,  衝突描述中嘗試工作內容的部分
  • svn_wc_conflict_reason_t,  衝突描述中衝突類型部分
  • svn_wc_conflict_result_t,  返回的衝突解決嘗試結果
  • svn_wc_conflict_choice_t,  用戶選擇動作的列表

客戶端通過設置他們的svn_client_ctx_tconflict_func字段提供了他們的callback函數,並可以通過對應的conflict_baton字段提供額外的callback狀態。

變更列表支持(changelist)(客戶端)

Subversion客戶端現在包含了變更列表(changelist)的改變,一組與選定名稱關聯的文件,當工作在同一個工作拷貝的不同集合的文件時這樣非常有效,Subversion1.5允許你爲每組文件關聯一個變更列表,大多數可以將一組文件作爲目標的命令現在也接受–changelist選項,會根據changelist的成員過濾目標,變更列表的成員可以使用changelist子命令編輯。

變更列表完全是客戶端控制的。他們不會發送到服務器,對同一個版本庫其他用戶都不可見。另外,--changelist 選項不是添加劑;如果一個文件在沒有--changelist的時候加入到目標的列表,它也不會加入進去,它不會管changelist的成員。當前,一個文件一次只能屬於一個變更列表,目錄不能作爲變更列表的成員。

下面的子命令支持--changelist選項:

  • changelist
  • commit
  • diff (only wc-wc and wc-repos cases)
  • info
  • propget
  • proplist
  • propset
  • propdel
  • revert
  • status
  • update
進一步閱讀
svn:externals中的相對URL,peg revisions(客戶端)

svn:externals 特性的兩個增強

對於URL的Peg revision語法

兼容性和新的語法:由於兼容性原因,1.5以前的svn:externals語法繼續不理解peg revisions,引入了一種支持URL中peg revisions的新語法。

以前的格式是:

   foo             http://example.com/repos/zig
   foo/bar -r 1234 http://example.com/repos/zag

不支持peg revisions,如下的外部定義不能工作(除非目錄名就是zig@HEAD and zag@HEAD):

   foo             http://example.com/repos/zig@HEAD
   foo/bar -r 1234 http://example.com/repos/zag@HEAD

新格式將跟在外部定義後面的路徑URL移動到第一位;如果有一個操作(-r)修訂版本,則在URL之前,下面是四個外部定義行:

   http://example.com/repos/zig foo1
   -r 1234 http://example.com/repos/zag foo/bar1
   http://example.com/repos/zig@HEAD foo2
   -r 1234 http://example.com/repos/zag@HEAD foo/bar2

換句話說,操作(“r”)和peg(“@”)都是允許,但都不是必須的。

對相對URL的支持

在Subversion1.5之前,svn:externals中的URL必須是絕對路徑,現在他們可以是相對的。現在支持四種相對外部引用。(在下面的例子裏,假設我們有兩種版本庫:一個是在http://example.com/svn/repos-1 ,另一個在http://example.com/svn/repos-2,我們檢出http://example.com/svn/repos-1/project1/trunk,而svn:externals 設置爲trunk。)

../

svn:externals屬性設置目錄的相對路徑,則URL是以../開始,例如:

   ../../project2/trunk common/project2/trunk

這就是將http://example.com/svn/repos-1/project2/trunk 加入到common/project2/trunk。外部URL相對於設置svn:externals屬性的目錄的URL,而不是寫到磁盤的外部的目錄。

^/

相對於庫的根。

   ^/project2/trunk common/project2/trunk

這就是將http://example.com/svn/repos-1/project2/trunk加入到common/project2/trunk

你可以容易使用相對URL來引用其他的版本庫:

   ^/../repos-2/foo/trunk common/foo/trunk

就是http://example.com/svn/repos-2/foo/trunk加入到common/foo/trunk

//

相對於模式,這就是拷貝了檢出或導出URL的模式到svn:externals,當同一個主機必須依賴於網絡位置按照不同的模式訪問;例如局域網的客戶端使用http://,而外部客戶使用svn+ssh://

   //example.com/svn/repos-1/project2/trunk common/project2/trunk

這將會把http://example.com/svn/repos-1/project2/trunk提取到common/project2/trunk,如果工作拷貝是通過svn+ssh://example.com/svn/repos-1/project1/trunk 檢出的,那麼URL將會是svn+ssh://example.com/svn/repos-1/project1/trunk

/

服務器root的相對URL,這是檢出或導出的模式和主機名的URL拷貝到svn:externals。

   /svn/repos-1/project2/trunk common/project2/trunk

這會提取http://example.com/svn/repos-1/project2/trunkcommon/project2/trunk。如果工作拷貝是從svn+ssh://example.com/svn/repos-1/project1/trunk 檢出,那麼URL將會是svn+ssh://example.com/svn/repos-1/project1/trunk

舊的svn:externals格式依然支持相對URL(不會支持peg revisions)。

當Subversion見到不使用絕對URL的externals ,會將第一個參數作爲相對URL,第二個作爲目標目錄。

進一步閱讀

See The svn:externals section of the Subversion Book.

ra_svn和svnserve的Cyrus SASL支持(服務器和客戶端)

來自Wikipedia:“SASL是網絡協議的認證和數據安全框架,它將認證機制與應用協議解耦,從理論上講,允許任何SASL支持的認證機制應用到使用SASL的應用協議上”

在實踐中,服務器發送會發送一組它支持的認證機制,客戶端會根據客戶端的支持選擇一種認證機制,並通知服務器這個決定。之後,會有一些信息交換,直到成功或者失敗發生,在後一種情況,允許客戶端重新認證。

svn:// 協議會一直支持這種類型的協商,然而只是實現了CRAM-MD5和ANONYMOUS。Cyrus SASL支持所有這些,此外,提供了其它如DIGEST-MD5, OTP (One-Time Passwords), GSSAPI (used for Kerberos authentication), NTLM (NT LAN Manager), SRP (Secure Remote Password)以及其他機制的支持。支持機制的準確列表依賴於SASL是如何編譯的,有一些還有外置依賴,或不是缺省編譯。另外,因爲每種機制實際上是一個共享庫,會在運行中加載,有許多分佈的包位於核心庫外單獨存放。

關於使用1.5並開啓SASL與1.5前的客戶端工作的更多信息請看兼容性部分,關於Subversion的SASL支持可以看sasl.txt

對於FSFS大規模開發的改進支持,通過sharding (服務器)

FSFS文件系統後端在各自的文件存放每個修訂版本,在Subversion1.5之前,所有的文件都存放在版本庫一個普通的目錄裏,現在新創建的FSFS庫會使用二級的目錄樹,每個目錄最多1000個文件。這種版本庫只能與Subversion1.5客戶端兼容,但是當然,Subversion1.5仍然可以使用以前格式的版本庫,而沒有問題。

這樣做的主要原因是允許修訂數量能夠超越文件系統的目錄樹的限制,當現代文件系統能夠成支持每個目錄有百萬條目,它會變得很慢,而且管理工具會變得笨拙或失敗。

關於FSFS sharding的更多信息可以看這個blog entry

svnadmin create創建後,使用版本庫之前,shard大小可以通過編輯“db/format”中的“layout sharded”來調整。

改進的FSFS優化,通過不可變的文件隔離(服務器)

FSFS版本庫永遠不會在寫入修訂版本後進行修改,儘管最好讓操作系統永遠緩存所有的文件,某些文件系統(例如NFS)缺省可以通過這種緩存獲益,現在FSFS版本庫爲此將不變的文件存放在子目錄“db/revs”和“db/txn-protorevs”,這允許這些目錄加載到開啓緩存(在Linux可以看nfs部分的“nocto”)的掛接點上。

因爲提交事務存放在db/txn-protorevs” 而不是”db/transactions”,後者的目錄不必在同一個掛接點,如果版本庫存放在較慢的文件系統(例如NFS),提交效率可以通過將目錄移動到本地磁盤(使用符號鏈)改進。如果你在一個網絡負載平衡器之後使用多個svn服務器,你必須配置負載平衡器在一個事務中轉向到同一個服務器,這通常叫做“客戶端喜好”。

WebDAV透明通過代理寫(服務器)

Subversion1.5引入了svnsync — 一提供從一個版本庫複製內容到另一個版本庫的工具。儘管很有用,但svnsync只能從一個版本庫拖入修訂版本,但是不能將額外的提交返回給master。Subversion1.5爲mod_dav_svn添加了WebDAV代理支持,有效的使用mod_dav_svn允許雙向的修訂版本歷史複製。

所有的客戶端與slave服務器交互,但是slave會透明的將所有的寫活動傳遞給master(根據需要重寫數據),slave實質上是隻讀的,但是它們本地都有一個完整的版本庫,服務器分流master服務器的讀壓力,某些情況下非常可觀。

如果使用支持HTTP DAV的緩存代理,這個模型非常有好處,在這個情況下,每個slave可以對應所有對應的只讀請求,而無需傳遞給master後端。

要求
  • Subversion 1.5或更新的。
  • Apache HTTP Server 2.2.0或更高,並開啓mod_proxy (許多mod_proxy 修正的bug沒有回到httpd的2.0版本)
實例配置

參與者:

  • Slave → slave.example.com (可以很多)
  • Master → master.example.com (可能只有一個)
  • A WebDAV client (ra_neon, ra_serf其他WebDAV客戶端)

客戶端做:


    % svn co http://slave.example.com/repos/slave/
    ...
    % svn ci
    % ...etc...

(客戶端可以操作如常)

每個slave配置:


    <Location /repos/slave>
      DAV svn
      SVNPath /my/local/copy/of/repos
      SVNMasterURI http://master.example.com/repos/master/
    </Location>

master必須有一個post-commit鉤子可以更新所有的slave,一個例子使用svnadmin dump/svnadmin load ,ssh作爲支持。svnsync可以完成同樣的事情。

此外,如果master版本庫支持鎖定,鎖定數據庫需要通過post-lock和post-unlock保持同步,將master狀態傳遞到slave。(用戶名保留作爲讀者的練習),如果不傳遞鎖定信息,用戶需要能夠精確的檢測是否有一個鎖定-但是鎖定會一直工作。

一個實例的同步腳本可能如下:


   #!/bin/sh
   REPOS="$1"
   REV="$2"
   SLAVE_HOST=slave.example.com
   SLAVE_PATH=/my/local/copy/of/repos

   # Ensure svnadmin is in $PATH on both this machine and the remote server!
   svnadmin dump --incremental -r$2 $1 > /tmp/$2.dump
   scp /tmp/$2.dump $SLAVE_HOST:$SLAVE_PATH
   ssh $SLAVE_HOST "svnadmin load $SLAVE_PATH < $SLAVE_PATH/$2.dump"
   ssh $SLAVE_HOST "rm $SLAVE_PATH/$2.dump"
   rm /tmp/$2.dump
進一步閱讀

關於WebDAV代理的更多信息可以看in the repository

改進和bug修正

Copy/move-related improvements (client and server)

The abilities and behavior of copy and move operations are significantly improved in 1.5+.

Improved copy-handling during updates (client and server)

A common problem in older versions of Subversion was the way in which svn update handled incoming copies and moves.

Consider this scenario: Harry runs svn move foo bar; svn commit, and meanwhile Sally makes local changes to ‘foo’, and then runs svn update. In earlier versions of Subversion, the server would send down a completely new file ‘bar’, and unversion the file ‘foo’ (if it had no uncommitted changes, Subversion would remove it entirely.) From Sally’s point of view, her changes seem to be lost; the newly added ‘bar’ file has the older content, and the file ‘foo’ has been taken out of version control.

In Subversion 1.5, the client and server both attempt to be smarter about this. The server doesn’t send a whole new file during the update, but rather instructions to copy something that likely already exists in the working copy. So Sally’s ‘foo’ file is copied to ‘bar’ (with local edits intact!).

In theory, this is the best-case scenario. There are a few caveats: this “proper copying” of existing working-copy resources only works on files, not (yet) on directories. Also, if an incoming move-operation deletes ‘foo’ before it attempts to copy it to ‘bar’, then the copy will fail, and the client reverts to the old behavior of fetching a pristine copy of the file from the repository. We hope to address this in svn 1.6.

See issue #503 for more.

Peg revisions (client)

Copy and move operations now accept sources with peg (”@”) revisions.

See issue #2546 for more.

Multiple working copy copy/move operations (client)

Clients may now perform chained copy/move operations locally on a single object in a working copy:

   svn mv path1 path2
   svn mv path2 path3

See issue #756 for more.

Improved handling multiple copy/move sources (client)

Clients now accept multiple sources for copy and move operations, with the ability to copy/move each of the sources to the specified directory. This mirrors the behavior of standard command-line copy and move tools, such as cp and mv. For example:

   svn mkdir new_subdir
   svn mv foo.txt bar.txt baz.txt new_subdir

In practice, this means users can take advantage of shell globbing when doing a local copy or move:

   svn cp *.c dir

Multiple source copy/move also works for all previously defined copy/move working copy and repository combinations.

See issue #747 for more.

Copy takes -rBASE (client)

Copy now understands the special revision “BASE” in a working copy (as in: “-rBASE“).

See issue #1643 for more.

Creation of intermediate directories with copy/move (client and server)

See the section on the new –parents option for more about this.

Cancellation improvements (client)

Clients operations are now significantly more responsive to cancellation (e.g. via control-c). In pre-1.5 releases, after directing an operation to stop, one sometimes had to wait for some time (e.g. while I/O occurred) before the operation would actually stop.

Command-line client improvements (client)

There are far too many enhancements and new options to the command-line client to list them all here. Aside from all the ones mentioned already in these release notes, below are a few more that we consider important, but please see the 1.5.0 section in the CHANGES file for a complete list.

New “resolve” subcommand replaces “resolved”

A new resolve subcommand replaces the “resolved” subcommand (the latter is deprecated, but still present for compatibility). The new subcommand takes a –accept=orig|mine|repo option to select which version of a file to retain (which means Subversion now supports batch-style conflict resolution).

See issue #2784 for more.

Create intermediate directories if asked

Add, mkdir, copy, and move take a new –parents option, which makes intermediate directories as necessary to create the destination path.

See issue #1776 for more

New –keep-local option retains path after delete.

Delete (remove) now takes a --keep-local option to retain its targets locally, so paths will not be removed even if unmodified.

Commit now takes a –with-revprop option.

Commit now takes a –with-revprop option allowing one to set revision properties

See issue #1976 for more.

Easier to try out experimental ra_serf DAV access module (client)

Subversion 1.4 introduced the experimental ra_serf repository access module for accessing HTTP[S] DAV Subversion servers. This uses the serf library instead of the Neon library which the original DAV support uses. serf supports pipelined requests which may lead to better performance. However, Subversion 1.4 required you to choose which module to use for accessing DAV servers at build time, which made it difficult to find out which module performs better for your usage patterns.

Subversion 1.5 allows you to build both modules at the same time; you can choose which library to use on a global or host-by-host basis by setting the http-library variable in your run-time server configuration file (~/.subversion/servers). In recognition of the fact that both libraries are DAV clients, we have renamed ra_dav to ra_neon.

API changes, improvements and language bindings (client and server)

There are too many new and revised APIs in Subversion 1.5.0 to even begin to list them all here. See the Subversion API Documentation page for general API information. If you develop a 3rd-party client application that uses Subversion APIs, you should probably look at the header files for the interfaces you use and see what’s changed.

One general change is that most APIs that formerly took a recurse parameter have been upgraded to accept a depth parameter instead, to enable the new sparse checkouts feature.

Language bindings have mostly been updated for the new APIs, though some may lag more than others.

Bug fixes (client and server)

A great many bugs have been fixed. See the 1.5.0 section in the CHANGES file for details.

Subversion 1.3.x series no longer supported

The Subversion 1.3.x line is no longer supported. This doesn’t mean that your 1.3 installation is doomed; if it works well and is all you need, that’s fine. “No longer supported” just means we’ve stopped accepting bug reports against 1.3.x versions, and will not make any more 1.3.x bugfix releases, except perhaps for absolutely critical security or data-loss bugs.

Subversion Dependencies Distribution: Binary Compatibility Issues

Background

APR 0.9.x and 1.x are binary-incompatible. This means if you are already using Subversion with APR 0.9.x, and then upgrade your libapr to 1.X without rebuilding Subversion, things will break. Things will also break if your Subversion server libraries are linked to one version of APR but your Apache HTTPD server is linked to a different version.

For a long time, Subversion’s main source distribution included APR 0.9.x, which was the latest available at the time, along with a few other things (e.g., Neon, zlib) that weren’t yet widespread on installation systems.

Subversion 1.5.0 Dependencies Distribution

Today, these dependencies are no longer exotic, so our source distribution contains just Subversion itself. Those building Subversion are expected to have the necessary libraries already installed, or to be able to fetch them easily. But for convenience, we still offer a “deps” distribution: it doesn’t contain Subversion, it just has source code for those third-party libraries.

Until Subversion 1.5.0, the deps distribution contained APR 0.9.x, but as of 1.5.0, we’re finally upgrading it to APR 1.x. This is because by now there are very few systems that will have binary compatibility issues, and of those, few are likely to build using the “deps” dist.

If you already have a Subversion installation using APR 0.9.x, it’s still possible to move to APR 1.x safely (although you are not required to, unless you use the deps dist). Just be sure to recompile Subversion, and Apache httpd if necessary, after upgrading APR.

Note that it’s perfectly safe to use APR 1.x from the beginning. In fact, we recommend it. If you’re building Subversion for the first time, there’s no compatibility issue to worry about, so just grab the latest version of APR (or use our deps dist).

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章