轉自:http://subversion.apache.org/faq.zh.htmlhtml
爲了接管CVS的用戶基礎。確切的說,咱們寫了一個新的版本控制系統,它和CVS很類似,可是它修正了之前CVS所沒有解決的許多問題。請看咱們的首頁。java
不是,Subversion一款開源/免費的軟件。CollabNet公司爲幾個全職的開發人員支付薪水,而且擁有相關代碼的版權,可是這個版權是一個Apache/BSD-風格的許可證,它徹底聽從於Debian Free Software Guidelines。換句話說,你能夠爲所欲爲的去下載,修改,或者從新發布新的版本,而不須要通過CollabNet公司或者其餘任何一我的的許可。node
是的,絕對能夠。它是一款已經準備好進入黃金時段的產品。python
Subversion從2000年開始開發,在一年以後成爲一個自足執行(self-hosting)的項目。在以後的一年,當咱們將其稱爲"alpha"版本的時候,Subversion已經被不少的我的開發人員所使用,並確實發揮了真正的做用。在那以後,有兩年多的時間被用來進行Bug追蹤(bugfixing)和加強穩定性(stabilization),直到咱們發佈了1.0版本。大多數的其它項目可能都會把產品的「1.0」版本叫作早期版本,可是咱們故意的儘量長的推遲了這個版本的發佈。咱們意識到不少人在他們最初使用了Subversion以後一直在等待1.0版本的發佈,而且對這個意義非凡的版本有着特別的期待,因此咱們在這樣一個版本上用了不少的時間而不至於讓他們失望。web
客戶端和服務器被設計成只要他們相互之間沒有超過一個主要的發行版本,就能夠協調工做。例如任何一個1.x的客戶端均可以和一個1.y的服務器協調工做。然而,若是客戶端和服務器的版本不相匹配,某些特性可能不能使用。算法
客戶端和服務器之間的兼容性策略記錄在Subversion Community Guide的「兼容性」一節裏面。shell
全部現代風格的操做系統,好比Unix, Win32, BeOS, OS/2, MacOS X。數據庫
Subversion是用ANSI C來寫的,而且使用了APR,也就是Apache Portable Runtime庫做爲可移植層。Subversion的客戶端將能夠運行在任何APR運行的地方,這是最重要的一點。Subversion服務器(例如,版本庫端)一樣,惟一的例外是在Berkeley DB的Win9x(Win95/Win98/WinME)做爲平臺的主機上,由於Berkeley DB在Win9x平臺上共享存儲器的有段問題。FSFS版本庫(從版本1.1開始引入)沒有這種限制;然而因爲Win9x對文件鎖定的支持限制,他們仍然不能在Win9x的平臺上工做。apache
重申一下,Subversion客戶端能夠運行在任何APR所運行的平臺上。Subversion服務器也能夠運行在任何APR平臺所能運行的平臺,可是不能在Win95/Win98/WinMe上管理版本庫。windows
不是。"Subversion文件系統"不是一個能夠裝在操做系統上的內核級的文件系統,相反,它是Subversion版本庫的接口,是一個版本文件系統,在某種意義上說,它能夠存儲一個文件目錄結構(樹)而且使這個目錄結構從一個修訂版本到下一個修訂版本的過程當中保留版本信息。訪問這個版本庫來編寫程序和使用其餘文件系統的API是很類似的,可是最大的不一樣在於,這個特殊的文件系統在你寫入的時候不會丟失數據。目錄結構(樹)的一些舊的狀態信息能夠被很容易的恢復,就像恢復到最近的狀態那樣容易。
運行Subversion服務器要依賴各方面的多種因素,好比說必定數量的用戶,常常性的提交,其它相關聯的服務器,版本庫的大小以及自定義版本庫的負載等。當使用Apache時,有可能Apache自己在內存的使用狀況將成爲最大的制約因素。請參閱郵件列表上對這個問題的討論,這裏有針對這個問題的明確的答案。
須要記住的是,在同一臺服務器上運行其它的應用程序,好比版本庫的瀏覽器一樣會使用內存,它是獨立於Subversion自己。
一般,和CVS本版庫相比,你能夠指望須要更少的服務器內存。
不用。Subversion是一系列的庫,它與一個命令行的客戶端相互配合工做。有兩類不一樣的Subversion的服務器進程,包括一個svnserve進程,這是一個小的相似CVS的pserver進程的獨立運行程序,另外一個是使用mod_dav_svn模塊的Apachehttpd-2.0。svnserve進程能夠說是一個經常使用協議,而mod_dav_svn進程使用了WebDAV做爲它的網絡協議。請參閱Subversion手冊第六章以瞭解更多的內容。
一句話:沒必要。
詳細的回答是:若是你僅僅是想去訪問一個版本庫,你只須要構建一個Subversion的客戶端。若是你想擁有一個網絡的版本庫,那麼你須要安裝Apache2或者一個「svnserve」服務器。
關於安裝一個能夠訪問的Subversion服務器的詳細信息,請參閱:Subversion手冊第六章。
沒必要,你能夠用svnserve做爲Subversion的服務器,它能夠很好的工做。
在使用Apache server時,若是你想使用分佈式創做和版本管理協議(WebDAV)和全部其餘一些好的功能特性,那麼是的,你須要Apache 2.0。可是無論怎樣,當你繼續在80端口運行Apache1.0的時候,你老是能夠在另一個不一樣的端口運行Apache2.0。不一樣版本的Apache能夠在同一臺機器上很好的和平相處。僅僅須要在改變httpd.conf文件中把Listen指令從80改爲8080,或者其餘你想要改爲的端口。而後確保在你公佈版本庫的URL的時候加以說明:(例如,http://svn.mydomain.com:8080/repos/blah/trunk/)。
咱們歷來沒有試圖在SCM系統上推到重來,開闢出一個新的天地,也沒有試圖徹底模仿每個SCM系統的好的特性,咱們只是要取代CVS。請參閱咱們的第一個問題。
首先,請注意Subversion沒有項目這個概念。版本庫只是存儲版本化的目錄樹 — 你能夠將某個子目錄看成項目,可是Subversion不會對其特殊對待。所以,對於一個項目的構成徹底由用戶本身解釋。(與之相似的branches和tags的習慣是創建在複製之上,而不是創建在Subversion的概念之上。)
每當你提交變動時,版本庫會在版本庫目錄樹總體上增長一個修訂版本,並將新的樹賦予一個新的修訂版本號,固然,大多數目錄樹和前一個修訂版本徹底同樣,只是部分被更改。
新修訂版本號碼是一個順序增長的標籤,會附加給每一個新增的樹,而不是這個修訂中的某個文件或目錄,然而,通俗來講,會使用修訂版本號碼來引用修訂中提交的變動;例如「r588中的變動」(「r588」是「修訂版本588」的簡寫)的真實含義是「版本庫目錄樹587和588的區別」,或者是另外一個說法「將目錄樹587變成588的變動」。
所以,不斷增長的修改版本號碼會以一個總體標示版本庫的進展;你一般不會使用修訂版本號碼來度量版本庫中特定項目的進展,固然,修訂版本號碼不該該做爲項目可見的發佈號碼,對此,你應該經過其餘機制來區別發佈,例如使用tags。
這個問題有些麻煩,由於好像每一個人對變動集的定義多少有些不一樣,或者至少對版本控制系統的變動集特性多少有些不一樣的指望。
基於這個討論的目的,這裏對變動集有一個簡單的定義:它是全部改變的惟一的名字的集合,這些改變可能包括對文件內容句法的編輯,目錄結構的改變,或者是一些元數據的從新組合。更加一般的理解,一個變動集僅僅是一個你所能進行參閱的補丁的名字。
Subversion按照一階對象的方式管理版本化目錄樹(版本庫是一個目錄樹數組),而變動集則是被推生出來的東西(經過比較相鄰的目錄樹)。Arch或Bitkeeper這類程序以相反方向建立:他們用一階對象的方式管理變動集(版本庫是一系列的補丁),而目錄樹則是由一系列的補丁組合而成。
從根本上來講,二者都不夠好:爭論至少能夠追溯到三十年之前。對於不一樣類型的軟件開發,各有利弊。如今咱們不打算討論這些,這裏我將解釋使用Subversion能怎麼作。
用Subversion,用一個全局的版本編號N來命名版本庫目錄樹:這是說版本庫是通過第N次提交。它還包括一些不明顯的變動集:若是你比較目錄樹N和目錄樹N-1,你能夠精確獲得提交的補丁。
所以,能夠很容易的想到,版本N不只僅是一個變動集。若是你用一個事件追蹤去管理bug,你能夠用版本號碼去引用特殊的補丁,這些補丁很適合bug。例如,「這個事件被穩定在9238版本。」一些人可能運行‘svn log -r9238’來閱讀對應Bug的補丁信息,運行‘svn diff -r9237:9238’來查看補丁自己。svn合併命令也是利用了版本號碼。只要在合併參數中指明結果集,就能夠把結果集從一個分支明確的合併到另外一個分支:‘svn merge -r9237:9238 branchURL’將合併結果集#9238到你的工做拷貝。
彷佛根據結果集構建和主要對象的構建同樣複雜,可是已經比CVS方便許多了。
Subversion 1.1(和後續版本)已經能夠把一個符號鏈置於版本控制之中,經過一個經常使用的svn add命令便可。
詳細:版本庫尚未一個關於符號鏈的內部概念,它存儲一個附加'svn:special'屬性的普通文件做爲「符號連接」。svn客戶端(在unix上)能夠看到屬性,而且在工做拷貝里轉換成一個符號鏈。Win32沒有符號鏈,因此一個win32的客戶端不會作任何的轉換:對象表現的像一個日常的文件。
可用的矢量Subversion logo在Subversion 版本庫的www文件夾下能夠獲得。
特別的是,EPS 版本,和一個Adobe 插圖文檔也是可用的。
若是你在閱讀這個常見問題回答以後,沒有找到你問題的答案,那麼你還有其餘的幾個資源能夠利用:
咱們的郵件列表爲了保持在一個適度的標準,因此你最初的郵件可能會被延遲經過,直到維護人員有機會讓它經過。一旦郵件容許經過,全部從相同的地址掛起的郵件將被自動支持,因此你應該不會再被拒絕。固然,若是你的發送地址改變了的話,你將不得再也不次讓維護人員檢測經過。
使用Subversion客戶端:
$ svn co http://svn.collab.net/repos/svn/trunk subversion
這將會從Subversion源文件目錄裏檢出一個名叫subersion的目錄到你的本機上。
請參閱 http://svn.collab.net/repos/svn/trunk/README;特別的,在第IV部分,即「快速指南」。
更詳細的資料,請閱讀Subversion手冊第五章。
試一下cvs2svn轉換工具,從http://cvs2svn.tigris.org/ (或者從這裏 特性列表和相關文檔)。cvs2svn是大多數人的選擇,可是若是有別的緣由使他不能知足你的要求,至少還有其餘兩種工具供你選擇:
也能夠參閱Subversion連接頁面。
Subversion支持經過代理訪問網絡。首先,修改配置文件中的"servers"部分,並指定你的代理服務器。配置文件所在目錄在不一樣的操做系統上可能不一樣,在Linux或 Unix系統中,一般是~/.subversion;在Windows系統中,一般是"%APPDATA%\Subversion"。(執行"echo %APPDATA%"顯示目錄的具體路徑,注意這是一個隱藏目錄。)
配置文件中的註釋描述了配置文件書寫的格式。若是配置文件還不存在,能夠取得最新版的svn,並執行任何svn命令,這將建立配置文件模板及其相應的目錄。
其次,請確認你的代理服務器支持全部Subversion必須的HTTP方法。有些代理服務器默認不支持如下命令:PROPFIND, REPORT, MERGE, MKACTIVITY, CHECKOUT。解決辦法依賴於你使用的代理服務器軟件,對於Squid,配置選項以下:
# TAG: extension_methods # Squid only knows about standardized HTTP request methods. # You can add up to 20 additional "extension" methods here. # #Default: # none extension_methods REPORT MERGE MKACTIVITY CHECKOUT
(Squid 2.4及其以後的版本支持PROPFIND.)
參見"Subversion用到的HTTP方法是有哪些?"來配置代理服務器來支持HTTP方法。
若是讓代理服務器支持Subversion訪問網絡很困難甚至是不可能的話,而你只想checkout Subversion的源代碼,你能夠繞過代理服務器。一些代理服務器封鎖了80端口,若是是這樣的話,能夠經過81端口訪問svn.collab.net代碼庫服務器。執行:
svn checkout http://svn.collab.net:81/repos/svn/trunk subversion
可能代理服務器會放行。另外一個辦法是經過SSL來checkout,SSL被大部分代理服務器所支持:
svn checkout https://svn.collab.net/repos/svn/trunk subversion
固然,你的svn客戶端應該支持ssl。在編譯源代碼的時候,在./configure時添加--with-ssl選項。執行svn --version能夠知道你的svn是否支持'https'。
一個簡單的選擇是使用svnserve服務器來代替。請參閱SVN手冊第6章中的詳細內容。
然而,若是你的管理員不但願你運行Apache,這極可能是他們不想讓你在3690端口運行一個客戶服務器,則備選答案是假定你的管理員贊成你使用現有的SSH設施。
若是你使用CVS,你可能已經使用SSH來登陸CVS服務器,ra_svn Subversion的訪問方法是和使用Subversion是相同的。僅僅是在你的版本庫的URL上加上一個"svn+ssh"的前綴。
$ svn checkout svn+ssh://your.domain.com/full/path/to/repository
這將使你的SSH的程序在遠程運行一個私有的'svnserve'進程,用你的用戶ID訪問版本庫,並經過加密管道將數據傳遞回來。
然而,另外的一種能夠用來替代的解決方案是將SSH端口轉向鏈接到經過ra_dav保護的服務器上。你能夠經過SSH鏈接到一個防火牆後的一個機器,這個機器能夠訪問Subversion服務器。注意,這個SSH服務器不須要與Subversion安裝在同一個機器上,能夠是,但不是必須是。
而後你能夠建立一個本地端口來鏈接在你家裏的Subversion版本庫的HTTP服務器。你能夠經過本地端口’鏈接‘Subversion版本庫。而後,請求將被經過SSH服務器’通道‘發送到你的Subversion服務器。
一個示例:在大家公司位於10.1.1.50(叫它svn-server.example.com)的防火牆後面設置了一個Subversion ra_dav,你的公司容許SSH經過公共方式訪問ssh-server.example.com,而在內部能夠經過http://svn-server.example.com/repos/ours訪問Subversion版本庫。
實例:那麼客戶端經過端口轉向鏈接ssh服務器,並經過端口轉向檢出
% ssh -L 8888:svn-server.example.com:80 me@ssh-server.example.com % svn checkout http://localhost:8888/repos/ours
請注意svn-server.example.com也可讓httpd實例被非信任用戶運行在無特權的端口上,這容許Subversion不須要root訪問權限。
Joe Orton註明
服務器對正在使用的MOVE和COPY請求頭的主機名字是很敏感的,因此這個地方你必需要當心—工做正常可能須要配置"ServerAlias localhost"。
一些SSH端口轉向的連接
這決定與你的項目的複雜度,若是你的項目是相關的,而且有可能要共享數據,那麼最好的方式是經過子目錄建立一個版本庫。像下面這樣子:
$ svnadmin create /repo/svn $ svn mkdir file:///repo/svn/projA $ svn mkdir file:///repo/svn/projB $ svn mkdir file:///repo/svn/projC
若是你的工程是徹底不相關的,而且他們之間不可能共享數據,這樣最好建立幾個獨立的徹底不相關的版本庫。
$ mkdir /repo/svn $ svnadmin create /repo/svn/projA $ svnadmin create /repo/svn/projB $ svnadmin create /repo/svn/projC
這兩種方式之間不一樣之處在於: (由 Ben Collins-Sussman解釋 <sussman@collab.net>):
若是你不在乎某個版本庫的徹底歷史,你能夠只是在某個版本庫爲另外一個項目建立一個新的目錄,而後導入另外一個項目。
若是你在乎兩邊的歷史,那麼你能夠使用'svnadmin dump'將一個版本庫的內容轉儲出來,而後使用'svnadmin load'加載到另外一個版本庫。原來的修訂版本號碼會取消,但你還有歷史。
Peter Davis <peter@pdavis.cx>也解釋了一種方法,能夠使用像CVS模塊那樣使用svn:
只要合併發生在不一樣的目錄樹,你能夠使用svn版的CVS模塊。
將svn:externals屬性設置到從其餘版本庫檢出的目錄上,不管原來的目錄是什麼時候檢出的。版本庫仍是分離的,可是從工做拷貝的角度看,他們好像合併了。若是你在導入的目錄中提交,也將會影響外部版本庫。
合併並不意味着徹底的乾淨:導入只是影響了工做拷貝,因此你應該不能使用第一個版本庫的URL訪問從第二個導入的模塊,他們都仍是有各自的URL。
也能夠看miscellaneous utilities,裏面有一些在合併不一樣版本庫時幫助選擇和重排序修訂版本的工具,特別如基本操做的perl腳本svn-merge-repos.pl和高級組織的python類SvnDumpTool。
若是你使用Berkeley DB做爲版本庫的後端(在Subversion 1.0和1.1這是默認值,此後不是默認值),咱們建議你不要將版本庫存放在遠程文件系統(例如,NFS)。雖然Berkeley DB數據庫和日誌文件能夠存放到遠程文件系統,可是Berkeley DB的共享區域文件不能夠放到遠程文件系統上,因此版本庫只有被一個文件系統客戶訪問時才能保證安全,並且那種狀況下並非全部的Subversion功能都在一個客戶下工做正常。
若是你使用FSFS做爲後端,那麼將版本庫存放到NFS服務器(應當是支持鎖定的服務器)也應當沒問題。
工做拷貝能夠存放到NFS(一個常見的場景是你的主目錄在NFS服務器上)上,在Linux NFS服務器上,由於在檢出時Subversion內部使用的重命名的量比較大,一些用戶報告應當關閉‘子目錄檢查(subtree checking)’應當關閉,若是關閉子目錄檢查的詳細信息能夠看NFS Howto Server Guide和exports(5)。
咱們至少接到一份對於經過SMB訪問形成工做拷貝楔住的報告,形成錯誤的服務器是版本很是老的Samba(2.2.7a),在新版本(3.0.6)Samba中並無再出現這個問題。
在Berkeley DB環境中,版本庫會在repos/db/子目錄存放全部的數據,這個環境會包含一組表和一組日誌文件(log.*)。Berkeley DB會記錄對錶所做的變動,這樣在出現中斷後可以恢復到一致的狀態(more info)。
若是你聽任無論(做爲版本庫管理員),日誌文件會不斷的生長,吞噬磁盤空間。在任什麼時候刻,Berkeley DB只使用很小一部分的日誌文件(能夠看這個帖子以及相關的線索);其他的能夠安全的刪除。若是你永久保存全部的日誌文件,理論上Berkeley DB可以根據這個文件回到出生的時刻。可是在實踐中,若是你進行了備份,就沒有必要在磁盤中浪費空間了。
能夠使用svnadmin
查看哪些日誌文件能夠刪除,你能夠經過crob程序完成這個任務。
$ svnadmin list-unused-dblogs /repos /repos/db/log.000003 /repos/db/log.000004 [...] $ svnadmin list-unused-dblogs /repos | xargs rm # disk space reclaimed!
你也能夠使用Berkeley DB的db_archive
命令:
$ db_archive -a -h /repos/db | xargs rm # disk space reclaimed!
還能夠看svnadmin hotcopy
或hotbackup.py
。
注意:若是你正在使用Berkeley DB 4.2,Subversion建立的版本庫會自動刪除日誌文件,若是你想關閉這個功能,能夠在svnadmin create
命令中使用--bdb-log-keep
選項。能夠參考Berkeley DB手冊中的 DB_LOG_AUTOREMOVE
參數。
試圖保證儘量少的用戶可以訪問版本庫,例如以某個用戶運行apache或'svnserve -d',那麼版本庫由這個用戶徹底擁有。不容許任何其餘的用戶經過file:///的URL訪問版本庫,必須只讓擁有版本庫的用戶運行'svnlook'和'svnadmin'。
若是你的客戶端經過file:///或svn+ssh://訪問,則沒法避免多個用戶的訪問。在那種狀況下,能夠閱讀第6章最後一小節,看一下最下面工具欄的「檢查列表」,它總結了讓這個場景更安全的步驟。
SELinux / Fedora Core 3+ / Red Hat Enterprise的用戶注意:做爲標準Unix許可的補充,在SELinux下,每一個文件、目錄和進程都有一個‘安全上下文’。當進程試圖訪問一個文件時,除了檢查Unix訪問許可,系統還會檢查進程的安全上下文與文件的安全上下文是否兼容。
而Fedora Core 3,隨SELinux一塊兒安裝,在默認狀況下Apache會在一個限制的安全上下文中運行。爲了在Apache下運行Subversion,你必須設置版本庫的安全上下文使之支持Apache的訪問(或者關閉對Apache的限制,若是你認爲這是過度當心)。chcon命令能夠用來設置文件的安全上下文(與chmod設置Unix訪問許可相似)。例如,一個用戶能夠這樣運行命令
$ chcon -R -h -t httpd_sys_content_t PATH_TO_REPOSITORY
設置安全上下文能夠成功的訪問版本庫。
某些客戶端操做是「只讀的」,例如檢出和更新。從訪問控制的角度,Apache會這樣處理。可是libsvn_fs(版本庫文件系統API)在生成增量樹的時候仍是須要寫臨時數據,因此訪問版本庫的進程應該可以讀寫訪問Berkeley DB的文件,才能完成功能。
尤爲是版本庫須要應答許多比較兩個目錄樹的「只讀」操做時,一個樹多是HEAD修訂版本,而另外一個則是臨時的事務-目錄樹 -- 所以許多寫權限。
這種限制只存在於Berkeley DB後端;FSFS後端並無顯示這種特性。
有某些特殊狀況下,你可能但願徹底的刪除你曾經提交文件的全部信息(或許有人意外的提交了一份保密的文檔)。可是這個操做不是很容易完成,由於Subversion有意被設計成決不丟失信息,修訂版本是基於上一個版本所構建的不可改變(immutable)的文件樹。從版本的歷史記錄裏刪除一個修訂版本將會形成多米諾骨牌效應,形成後繼版本的混亂,還有可能使得全部的工做拷貝無效。
項目有計劃在將來實現一個svnadmin obliterate命令,可以完成永久刪除信息的任務(能夠看issue 516。)
如今,你只有求助於你版本庫的svnadmin dump命令,將轉儲文件通過svndumpfilter過濾(排除錯誤的路徑)傳遞給svnadmin load命令,請參閱Subversion手冊第五章的相關詳細信息。
日誌信息做爲每一個修訂版本的附加屬性保存在版本庫,默認狀況下,日誌信息屬性(svn:log)不能在提交後修改。這是由於對於修訂版本屬性(svn:log是其中一個)的修改會致使之前的屬性永久的消失,Subversion會防止這種意外狀況發生。可是,仍是有一些方法能夠修改修訂版本屬性。
第一種方法是讓版本庫管理員容許修訂版本屬性修改,這能夠經過建立"pre-revprop-change"(更多相關細節能夠看Subversion手冊的這個小節)。鉤子"pre-revprop-change"能夠在修改以前訪問老的日誌信息(例如,經過發送一個郵件),因此能夠以某種方式保存它(例如,經過發送郵件)。一旦開啓了修訂版本屬性修改,你能夠經過svn propedit或svn propset的--revprop選項修改修訂版本屬性,就像下面這個:
$ svn propedit -r N --revprop svn:log URL $ svn propset -r N --revprop svn:log "new log message" URL
這裏N是但願修改的日誌信息的修訂版本號碼,而URL是版本庫的位置。若是你從工做拷貝運行這個命令,你能夠省略URL。
第二種方法是經過svnadmin setlog修改日誌信息。這必須經過引用版本庫的文件系統位置來執行,你不能使用這個命令遠程修改版本庫。
$ svnadmin setlog REPOS_PATH -r N FILE
這裏REPOS_PATH是版本庫的位置,而N是你但願修改日誌信息的修訂版本,而FILE是包含新日誌信息的文件。若是"pre-revprop-change"鉤子不存在(或者由於鉤子腳本的緣由你但願繞過),你仍是能夠經過--bypass-hooks選項實現。然而,若是你要使用這個選項,要很是當心。你會繞過諸如變動的郵件提醒,或者保存修訂版本屬性的備份系統。
首先,看一下Subversion Community Guide。
一旦你消化了這些內容,能夠在dev郵件列表發送一個題目有[PATCH]的郵件,並在郵件中包含你的補丁(除非你的郵件客戶端會徹底處理它),不久以後就會有提交者撿起來,應用它(做出合適的格式化或內容變動),並將其檢入。
基本的過程看起來以下:
$ svn co http://svn.collab.net/repos/svn/trunk subversion $ cd subversion/www [ make changes to faq.html ] $ svn diff faq.html > /tmp/foo $ Mail -s "[PATCH] FAQ updates" < /tmp/foo
固然,你的郵件應當包含補丁完成什麼功能的解釋,按照Subversion Community Guide所說的,可是你已經知道了,由於在你Hack以前已經徹底閱讀和理解,不是嗎?:)
例如,假設你但願把/etc下的一些文件歸入版本控制:
# svn mkdir file:///root/svn-repository/etc \ -m "Make a directory in the repository to correspond to /etc" # cd /etc # svn checkout file:///root/svn-repository/etc . # svn add apache samba alsa X11 # svn commit -m "Initial version of my config files"
這裏利用了svn checkout的一個非當即但明顯的優點:你能夠從版本庫直接檢出一個目錄到已存在的目錄,這裏,咱們首先在版本庫建立一個目錄,而後將其檢出到已存在的目錄/etc,將/etc目錄變成工做拷貝。一旦完成,你能夠使用普通的svn add命令選擇文件和子目錄進入版本庫。
這是svn import的一個加強問題,它本應該可以在導入目錄樹時自動建立工做拷貝;能夠看issue 1328。
Subversion的版本庫數據庫模式在開發中會偶爾改變,使用1.0之前的Subversion開發版本建立的老版本庫在升級時須要以下操做。若是在發佈X和Y之間的模式發生變動,則版本庫管理員升級到Y的時候必須以下操做:
關於轉儲和加載的更多信息能夠看Subversion手冊的這個小節。
注意:大多數Subversion的升級不會須要轉儲和加載,若是某個版本須要,新版本的發佈聲明和CHANGES文件會顯著說明這一點。若是你沒有看到這個說明,那麼應該是沒有模式變動,也就沒有轉儲/加載的必要。
TortoiseSVN有個在Windows下設置Subversion服務器的完美文檔,能夠看http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-serversetup.html#tsvn-serversetup-apache-5中的SSPI authentication小節。
配置中比較重要的一部分是這幾行:
SSPIOfferBasic On
若是沒有這行,支持SSPI的瀏覽器會提示用戶輸入憑證,可是不支持SSPI的客戶端例如Subversion就不會提示。(當前版本的Neon - Subversion的HTTP庫 - 只能處理基本的認證。)由於客戶端永遠不會被請求憑證,任何須要認證的操做都會失敗。添加這一行告訴mod_auth_sspi對客戶端使用基本認證,但使用Windows域控制器認證憑證。
若是可能,咱們推薦你使用".svn",然而,若是你在Windows下使用ASP.NET,你可能須要按這裏的介紹設置環境變量SVN_ASP_DOT_NET_HACK。
或者你能夠使用一個徹底自定義的管理區域名稱,咱們反對這樣作,由於你的工做拷貝可能沒法與你的Subversion客戶端協調工做,然而,若是你喜歡,只須要將subversion/include/svn_wc.h的這一行從
#define SVN_WC_ADM_DIR_NAME ".svn"
修改成(例如)
#define SVN_WC_ADM_DIR_NAME "SVN"
而後從新編譯客戶端。
這個問題在兩種狀況下會發生。若是你的操做系統使用的文件系統對大小寫不敏感,例如windows系統,當你在添加文件的時候,你可能會不當心的添加一個文件名大小寫錯誤的文件。或者,你可能只是想改變版本庫中已有文件的大小寫。
若是你是在一個大小寫敏感的文件系統上工做,那基本上就不會出現這樣的問題。直接將文件改爲新的名字。例如,
svn mv file.java File.java
但這樣的方式在windows這類大小寫不敏感的文件系統上是不能正常運做的。在windows下,你只能臨時地將文件拷貝到其餘地方,而後從Subversion中刪除該文件,而後從新添加名字大小寫正確的文件副本。或者更好的辦法就是對Subversion的URL執行移動操做。推薦使用操做URL的方法,由於這樣能夠保持文件的歷史日誌,並且可以當即生效。
儘管如此,這兩種方式都會致使windows下的工做拷貝出現一些問題,由於當試圖更新文件名產生衝突的文件的時候,windows仍是會不知所措。(你可能會獲得一條消息如:svn: Failed to add file 'File.java': object of the same name already exists)。一個解決這個問題的辦法就是刪除工做拷貝而後從新檢出。若是你不想這麼作的話,那麼你就必須執行上面提到的兩個步驟來更新。
對於每一個大小寫錯誤的文件,執行下面的命令將會改變大小寫:
svn mv svn://svnserver/path/to/file.java svn://svnserver/path/to/File.java
要更新工做拷貝,你先得轉到相關的目錄,而後執行:
svn update file.java svn update
第一步的更新會從你的工做拷貝中刪除file.java,第二步更新會添加File.java,這樣就會生成一個正確的工做拷貝。或者若是你有不少這種問題的文件,你能夠按下面的方式來更新工做拷貝:
svn update * svn update
就像你看到的,添加一個大小寫錯誤的文件在文件系統大小寫不敏感的操做系統上,是須要一些小技巧來修正的。因此最好當你第一次添加文件的時候,一次性就添加對了。爲了防止相似的問題再發生,你能夠建立一個pre-commit的鉤子腳本,在其中調用文件check-case-insensitive.pl。這個文件放在Subversion的源代碼包裏,在contrib/hook-scripts目錄中
Subversion每次都將整個版本庫的版本號整個進行自增,因此它不能將關鍵詞替換成你想要的數字 - 它可能不得不在每次更新或者提交時對工做拷貝中的每一個文件進行搜索或者修改。
你想要的信息(你的工做拷貝的版本號)能夠經過svnversion命令來獲取;你能夠根據指定的工做拷貝的路徑提供其版本相關的信息(更多細節參考svnversion --help)。
你能夠將其組合到你的構建或發佈過程當中,以獲取須要存放到源代碼的信息。例如,在一個基於GNU make的構建環境中,在你的Makefile中添加以下的信息:
## ## To use this, in yourfile.c do something like this: ## printf("this program was compiled from SVN revision %s\n",SVN_REV); ## SVNDEF := -D'SVN_REV="$(shell svnversion -n .)"' CFLAGS := $(SVNDEF) ... continue with your other flags ...
(注意這段代碼在非GNU版本的make中無效,若是你的構建過程須要可移植,請不要使用它。)
或者使用如這些方法:
## ## on every build, record the working copy revision string ## svn_version.c: FORCE echo -n 'const char* svn_version(void) { const char* SVN_Version = "' \ > svn_version.c svnversion -n . >> svn_version.c echo '"; return SVN_Version; }' >> svn_version.c ## ## Then any executable that links in svn_version.o will be able ## to call the function svn_version() to get a string that ## describes exactly what revision was built. ##
Windows用戶會但願使用SubWCRev.exe,TortoiseSVN的下載頁面就有;能夠用當前工做拷貝的修訂版本替換給定文件中的全部$WCREV$標籤。
沒有。在CVS中沒有對應的$Log$關鍵字,若是你但願將日誌信息輸入某個特定文件,你能夠使用'svn log your-file-name'或'svn log url-to-your-file'。郵件列表中有幾個解釋$Log$缺點的例子:
「當你開始合併分支之間的變動時,$Log$會是一個徹底的夢魘。你必定會在這裏獲得衝突 -- 由於關鍵字的本性 -- 很難簡單的自動解決衝突。」
並且:
Subversion的日誌信息是能夠改變的,能夠經過設置svn:log修訂版本屬性修改。因此在任意文件擴展$Log:$會形成數據的過期,更新操做可能須要訪問全部出現$Log:$關鍵字的文件,即便這些文件沒有其餘的變動。
我對此並不在乎,我仍是指望使用它,你能實現嗎?
不能,咱們本身沒有計劃實現它,也不會接受實現這個特性的補丁。若是你但願發佈包含某種變動日誌的文件,你能夠在你的構建系統中跳出這個限制。
答案是:不要將文件歸入版本控制,而是將文件的模板歸入版本控制,例如「file.tmpl」。
而後,在初始化的‘svn checkout’以後,讓你的用戶(或你的構建系統)執行經過普通的操做系統複製將文件修改成正確的文件名,文件未版本化,因此毫不會提交。而且若是你但願,你能夠將文件加入到父目錄的svn:ignore屬性中,這樣它就不會在‘svn status’命令中顯示‘?’。
ssh擁有本身的密碼短語和認證緩存模式,它的認證緩存是Subversion以外的,須要獨立於Subversion設置。
OpenSSH使用ssh-keygen建立密鑰、經過ssh-agent緩存密碼短語、使用ssh-add將密碼短語添加到代理緩存中。一個簡化ssh-agent使用的腳本是keychain。在Windows下,PuTTY是一個流行的ssh客戶端選擇;將OpenSSH密鑰導入到pageant並緩存密碼短語能夠看PuTTYgen。
設置ssh-agent已經超出了本文的範圍,可是在Google中搜索「ssh-agent」能夠快速獲得答案,或者若是你沒有耐心,能夠是看這些:
http://mah.everybody.org/docs/ssh http://kimmo.suominen.com/docs/ssh/
注意:這裏都假設你使用了OpenSSH。也有一些其餘的ssh實現,大概它們也實現了這些功能,可是咱們不知道具體的方法。
你已經對修改過各類諸如.bash_profile的登陸文件,可是沒有效果!那是由於當Subversion客戶端調用ssh時會忽略那些文件。可是沒有必要修改PATH;相反,你能夠直接在svnserve命令中使用ssh的徹底名,下面是一個例子:
對於每一個須要經過svn+ssh訪問的用戶,生成一個新的Subversion使用的ssh公鑰對—不是用來登錄的。讓他們給密鑰對不一樣的名稱,例如~/.ssh/id_dsa.subversion。將密鑰的公共部分添加到服務器主機的~/.ssh/authorized_keys中,在開始部分包含ssh-rsa或ssh-dss以及一些幻數的行中,以下:
以前 |
---|
ssh-dss AAAAB3Nblahblahblahblah |
以後 |
command="/opt/subversion/bin/svnserve -t" ssh-dss AAAAB3Nblahblahblahblah |
很明顯,須要將/opt/subversion/bin/svnserve替換爲你主機上的相應值。你也會但願在命令行指明Subversion版本庫的徹底路徑(經過-r選項),節省用戶使用時的輸入。
command=魔法可讓遠程主機的sshd調用svnserve,即便你的用戶嘗試運行其餘命令,更多細節能夠看sshd(8)的man頁(AUTHORIZED_KEYS FILE FORMAT部分)。
如今當你的用戶運行Subversion客戶端時,請肯定他們有一個SVN_SSH環境變量是「指向」他們密鑰對的私有部分,經過下面的方法(Bourne Again shell):
SVN_SSH="ssh -i $HOME/.ssh/id_dsa.subversion" export SVN_SSH
這個主題的詳細討論能夠看這個文件。
Subversion缺省狀況下不會修改文件的內容;你能夠設置svn:eol-style或svn:keywords屬性實現這個功能。這讓Subversion比CVS的缺省行爲模式更加安全,可是安全也帶來了不便。
第一個問題的答案是:設置全部已經進入版本庫的文件,將會有點困難。你所要作的是在每一個文件(工做拷貝文件)上執行svn propset,而後執行svn commit,經過腳本應該能夠幫助你作這件事。
可是對之後的文件呢?很不幸,沒有在服務端自動設置提交文件屬性的機制。這意味着你須要讓你的用戶記住在每一個svn add的文件上添加屬性,幸運的是,有一個客戶端的工具能夠幫助咱們作這件事,能夠閱讀本書的auto-props特性。你須要保證全部的用戶配置了合適的自動化屬性。
你能夠寫一個pre-commit鉤子腳原本拒絕忘記在新文件添加屬性的提交(例子能夠看http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/check-mime-type.pl)。然而這個方法有點過激了,例如某人忘記了設置svn:eol-style,那麼在其餘系統上用戶很快就會注意到,一旦發現,能夠很簡單的修正:只要設置正確的值,並提交。
注意:許多用戶指望獲得服務器「自動廣播」運行中設置的特性,例如自動化屬性設置。對此已經有了一個特性請求(issue 1974),然而這個特性還存在爭議,尚未去實現。
Subversion命令行客戶端會調用經過環境變量SVN_EDITOR. 定義的編輯器,這個環境變量以及要編輯日誌的臨時文件會直接傳遞給操做系統。
由於是要將SVN_EDITOR的字符串傳遞給系統命令行,因此若是你不加引號,編輯器名稱中的空格或路徑中的空格會形成錯誤。
例如,在Windows下,若是你的編輯器在C:\Program Files\Posix Tools\bin\vi
,你須要這樣設置環境變量:
set SVN_EDITOR="C:\Program Files\Posix Tools\bin\vi"
請注意沒有必要在windows下回避引號,由於他們不是set
命令語法的一部分。
而在UNIX系統中,你須要聽從你shell的特定方法來設定變量,例如在bash shell中,應該這樣:
SVN_EDITOR='"/usr/local/more editors/bin/xemacs"' export SVN_EDITOR
若是調用編輯器須要命令行選項,只要在SVN_EDITOR環境變量的編輯器名稱後面輸入選項,就像你平時調用它時那樣。例如,若是你的編輯器須要-nx -r
選項,能夠按照下面的方式設置:
在Windows下:
set SVN_EDITOR="C:\Program Files\Posix Tools\bin\vi" -nx -r
在UNIX/bash中:
SVN_EDITOR='"/usr/local/more editors/bin/xemacs" -nx -r' export SVN_EDITOR
請注意SVN_EDITOR是Subversion特定的設置編輯器的環境變量,Subversion也支持使用更廣泛的EDITOR環境變量,可是若是你但願一些對於Subversion特殊的行爲方式,最好仍是使用SVN_EDITOR變量。
若是它是一個活動的版本庫,那麼對於這個問題最簡單的答案是「你安裝的Berkeley DB的版本」。可是,若是它是備份的或其它未知源獲得的版本庫,你對其的Berkeley DB版本一無所知,下面是你肯定它的方法:
運行命令查看版本庫中的高位計數文件db/log.*中位移12到16(10進制)的兩個4字節的整數。這裏是GNU od的例子:「od -j12 -N8 -tx4 log.<number>」。而這裏是Mac OS X hexdump的例子:「hexdump -s12 -n8 -x log.<number>」。第一個整數必定是幻數0x00040988,用來註明這是Berkeley DB日誌文件,第二個數字是日誌格式版本 - 能夠使用下面的表格和Berkeley DB的版本匹配:
日誌格式版本 | Berkeley DB版本 |
---|---|
5 (0x00000005) | 4.0 |
7 (0x00000007) | 4.1 |
8 (0x00000008) | 4.2 |
10 (0x0000000a) | 4.3 |
11 (0x0000000b) | 4.4 |
12 (0x0000000c) | 4.5 |
13 (0x0000000d) | 4.6 |
這個早已經解決,能夠經過爲版本庫添加post-commit鉤子腳本簡單實現,能夠讀一下手冊第5章關於鉤子腳本的內容,基本的思想是讓「活動站點」變成一個普通的工做拷貝,讓post-commit在工做拷貝中執行‘svn update’。
在實踐中,有許多地方須要當心。執行提交的服務器程序(svnserve或apache)也是執行post-commit鉤子腳本的程序,這意味着程序必須有正確的更新工做拷貝的訪問許可。換句話說,運行svnserve或apache的用戶應該擁有工做拷貝 -- 或至少工做拷貝設置了合適的訪問許可。
若是服務器須要更新它並不擁有的工做拷貝(例如,用戶joe的~/public_html/區域),一個技巧是建立一個+s的二進制程序運行更新,由於Unix不容許爲腳本運行+s,編譯一個小的C程序:
#include <stddef.h> #include <stdlib.h> #include <unistd.h> int main(void) { execl("/usr/local/bin/svn", "svn", "update", "/home/joe/public_html/", (const char *) NULL); return(EXIT_FAILURE); }
... 而後對二進制程序chmod +s,並確認它確實被用戶‘joe’全部,而後在post-commit鉤子中,添加一行運行二進程程序。
若是在讓鉤子運行時發生了問題,能夠看「爲何個人鉤子腳本都不能正常工做?」。
另外,你可能但願防止apache把工做拷貝中的.svn/目錄暴露出去,在你的httpd.conf添加下面的內容:
# Disallow browsing of Subversion working copy administrative dirs. <DirectoryMatch "^/.*/\.svn/"> Order deny,allow Deny from all </DirectoryMatch>
Subversion不支持檢出單個文件,它只支持檢出目錄結構。
然而,你能夠使用‘svn export’來導出單個文件,這會得到文件的內容,只是不會建立版本化的工做拷貝。
你不須要檢測,你也最好不要嘗試去作這樣的檢測。
工做拷貝的基本設計有兩個原則:(1) 你能夠任意編輯文件,而後(2)使用Subversion客戶端執行任何樹目錄的改動(增長、刪除、移動、拷貝)。若是這兩個原則可以很好的遵照,那麼客戶端就能夠順利的維護工做拷貝。若是重命名或者其餘改動是在Subversion以外進行的,那麼UI就會被破壞,工做拷貝也可能發生問題。客戶端不能猜想究竟發生了什麼事。
人們有時候會遇到這樣的錯誤,由於他們想要把版本控制變得透明化。他們誘使用戶使用一份工做拷貝,而後在稍候運行一個腳本,這個腳本會猜想用戶作了什麼樣的操做,而後執行相應的客戶端命令。不幸的是,這樣的方式只能在短時間內正常工做。‘svn status’會顯示出缺失條目或者未被歸入版本控制的條目,這些條目在腳本運行的時候會自動的被‘svn rm’或者‘svn add’。但若是發生了文件移動或者拷貝,那麼你就不那麼幸運了。即便腳本有很是可靠的方法來檢測這些動做,但‘svn mv’和‘svn cp’不能在這些操做已經完成的狀況下運行。
總的來講,工做拷貝必須整個放置在Subversion的版本控制之下,Subversion原本就不是設計成對用戶透明的。若是你想要得到這種透明性,那麼你應該創建一個apache服務器,而後本書附錄C使用的「SVNAutoversioning」特性。這將容許用戶將版本庫掛載成一個網絡磁盤的形式,任何對這個磁盤的修改,都會自動提交到遠程服務器上。
對於1.4.0及之後的版本,你能夠查看這裏。
對於1.4.0之前的版本,svnserve二進制自己並不能夠被安裝成一個windows服務,但有不少「service wrappers」能夠完成同樣的工做。例如:
在 TortoiseSVN手冊還有一點內容關於怎麼將svnserve安裝成服務的形式。
有三步:
假設你在/svn/myrepos目錄中放置了一個版本庫,使用的是BDB,你想要將其轉換成FSFS:
一旦一切工做正常後,刪除舊的版本庫便可。
若是要反過來操做,即從FSFS移植到BDB,只須要改變svnadmin create命令,將其指定爲BDB便可。
當你第一次添加或者導入文件到Subversion中時,Subversion會檢測該文件是不是二進制文件。目前,Subversion的策略是隻檢測文件的前1024個字節;若是每一個字節都是0,或者超過15%都是非ASCII碼可打印字符的話,那麼Subversion就認定該文件是二進制文件。這種啓發式方法未來可能會改進。
若是Subversion認定文件是二進制文件,那麼這個文件就會自動添加svn:mime-type屬性,並設置爲「application/octet-stream」。(你隨時能夠使用auto-props特性來重寫這樣的行爲,或者使用svn propset手動設置屬性。)
Subversion對如下的文件作普通文本處理:
全部其餘文件都將被視爲二進制文件處理,這意味着Subversion:
在其餘方面,Subversion將二進制文件和其餘文本文件同樣對待,例如,若是你設置了svn:keywords或者svn:eol-style屬性,Subversion會在二進制文件中執行關鍵詞替換或者行轉換。
須要注意,無論是否是二進制文件,都不會影響版本庫中用來存儲文件變動的空間大小,也不會影響客戶端和服務端之間的通信量。出於存儲和傳輸考慮,Subversion使用的是對二進制文件和普通文本文件一致處理的diffing方法;這和‘svn diff’使用的diffing方法徹底不相關。
svn diff沒有一個選項能夠作到這一點,可是
svn log -vq -r10徹底能夠實現你的目的;
svn log -vq -r123:456 | egrep '^ {3}[ADMR] ' | cut -c6- | sort | uniq
你或許是想作這樣一些事情
svn mv svn://server/trunk/stuff/* svn://server/trunk/some-other-dir
可是卻失敗了
svn: Path 'svn://server/trunk/stuff/*' does not exist in revision 123
... 或者還有其餘一些看起來不可理解的錯誤信息。
簡而言之,很不幸:Subversion沒有內置這樣的方法來進行這樣一種操做;許多其餘的命令,例如mv,不會接受任意數目的參數...在任何狀況下,Subversion都不會擴展如shell所支持的「*」號通配符。
若是你恰好有一個工做拷貝包含了和目標目錄一摸同樣的源文件,那麼你能夠使用你的shell中的通配符特性來完成移動文件的目的,例如(在bash下):
for i in stuff/*; do svn mv $i some-other-dir; done svn ci -m "moved all the stuff into some other dir"
在任何狀況下,你均可以將源文件的名字拼成一個列表,而後使用「svn mv」命令對列表中的每一項都執行一樣的指令,就像下面所作的同樣:
s=svn://server/trunk/stuff/ svn ls "$s" | \ while read f do svn mv "$s/$f" svn://server/trunk/some-other-dir -m "Moved just one file" done
可是須要注意的是,這樣會形成每一個文件都執行一次提交動做,這和上面的方法(使用工做拷貝)不一樣,上面的方法總共就會執行一次提交動做。
有一個程序叫「svnmucc」或者「mucc」能夠解決你的這個問題,不過它依賴於你的Subversion版本號,它的源代碼已經發布在Subversion中了(對於Subversion 1.4以及更早的版本,這個工具的源文件放置在/contrib/client-side/mucc/mucc.c,對於1.5及以後的版本,則在/tools/client-side/svnmucc/svnmucc.c能夠找到)。
注意:隨着1.5版本的正式發佈,Subversion事實上容許你一次性同時「cp」和「mv」多個文件。
人們一般但願使用Subversion去跟蹤他們的變化的第三方代碼,甚至從第三的代碼進行升級,換句話說,他們想維護他們本身的一個分支,與此同時仍然但願從上游的代碼併入新的發佈。這一般被叫作供方分支(這個術語早於Subversion),Subversion維護這種分支的技術能夠看這個描述。
若是供方代碼是遠程的主機上的Subversion版本庫,你能夠使用Piston來管理你的供方代碼拷貝。
最後,若是使用svn_load_dirs.pl花太多時間的話,或者你正在尋找一個偷懶的方案,則能夠參考Jon Stevens的漸進介紹如何使用Subversion供方分支。這種解決方案在你拷貝新的代碼去覆蓋舊代碼的時候並不能利用Subversion後端的節省空間特性換;在這種解決方案中,每一份導入的供方代碼都會是一個新的拷貝,相同的文件不會節省存儲空間。
版本庫使用的Berkeley DB數據庫很容易受到破壞。若是進程退出時沒有正常關閉數據庫,那麼數據庫就處在非正常狀態中。常見的緣由多是:
多數狀況下,你能夠執行"svnadmin recover",這個命令能夠將版本庫回退到上一個正常狀態,詳細解釋請見bdb-recovery。注意,當頻繁的checkout和update且磁盤空間用盡的時候,可能致使版本庫處於沒法恢復的狀態(因此請多作備份)。
進程崩潰,被殺死以及磁盤空間用盡都是極端狀況。訪問權限問題多是更常見的緣由:當一個進程訪問版本庫且改變了版本庫的全部者或訪問權限,那麼另外一個訪問這個版本庫的進程可能被阻塞在訪問權限上。
避免這種狀況出現的最好辦法是正確設置你的版本庫的全部者和權限。查看更多信息。
你的版本庫沒有壞掉,數據也沒有丟失。當你的進程直接訪問版本庫(mod_dav_svn、svnlook、svnadmin,或經過‘file://’)的時候,進程將直接經過Berkeley DB來訪問版本庫。Berkekey DB包含日誌系統,也就是說全部的操做在執行前都被記錄在日誌中。當你的進程崩潰(Control-C,或段錯誤),遺留下文件鎖,它記錄了全部未完成操做的信息。此時全部試圖訪問數據庫的進程將由於要訪問文件鎖而被掛起。要想解除文件鎖,你能夠調用Berkeley DB來完成全部未完成的操做或者回退到前一個正常狀態。
警告:當一個進程正在訪問版本庫,而你又試圖恢復版本庫的時候,版本庫可能會嚴重損壞。
在你恢復數據庫以前,請確保沒有其餘進程在訪問版本庫(關閉Apache, 去掉'svn'的執行權限) 。確認你是以數據庫全部者及管理員的用戶進行操做的,而不是root用戶。不然數據庫將只能被root用戶訪問,而其餘用戶(你本身或Apache)將沒法對數據庫進行操做。同時,還要確保umask被正確設置,不然其餘隸屬與能夠訪問該數據庫的組的用戶可能沒法對數據庫進行操做。
執行:
svnadmin recover /path/to/repos
當命令執行完畢, 檢查版本庫db
目錄的訪問權限
有時"svnadmin recover"會失敗,錯誤信息以下:
Repository lock acquired. Please wait; recovering the repository may take some time... svnadmin: DB_RUNRECOVERY: Fatal error, run database recovery svnadmin: bdb: Recovery function for LSN 175 7066018 failed on backward pass svnadmin: bdb: PANIC: No such file or directory svnadmin: bdb: PANIC: fatal region error detected; run recovery
或者:
Repository lock acquired. Please wait; recovering the repository may take some time... svn: DB_RUNRECOVERY: Fatal error, run database recovery svn: bdb: DB_ENV->log_flush: LSN of 115/802071 past current end-of-log of 115/731460 svn: bdb: Database environment corrupt; the wrong log files may have been removed or incompatible database files imported from another environment [...] svn: bdb: changes: unable to flush page: 0 svn: bdb: txn_checkpoint: failed to flush the buffer cache Invalid argument svn: bdb: PANIC: Invalid argument svn: bdb: PANIC: fatal region error detected; run recovery svn: bdb: PANIC: fatal region error detected; run recovery [...]
這種狀況下能夠試試Berkeley DB的工具db_recover (參見db_recover文檔).這個命令一般在Berkeley DB安裝目錄的子目錄"bin/"中, 例如你從源代碼安裝的Berkeley DB,命令多是/usr/local/BerkeleyDB.4.2/bin/db_recover;或在某些系統中預安裝的Berkeley DB,多是 /usr/bin/db_recover.若是你的系統中安裝了多個版本的 Berkeley DB,請確保使用匹配版本庫的Berkeley DB版本
執行db_recover,附帶參數"-c" ("災難恢復").你還能夠附帶 "-v"來看到執行的詳細信息, "-h"指定被恢復的數據庫。例如:
db_recover -c -v -h /path/to/repos/db
用版本庫的擁有者的賬號執行這個命令,同時,請絕對確保沒有其餘進程在 訪問版本庫。(例如,關閉svnserve或)。
若是你經過http://來訪問版本庫,"Cannot allocate memory"應該出如今httpd服務器的日誌中,像下面這樣:
[Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] (20014) Error string not specified yet: Berkeley DB error while opening 'strings' table for filesystem /usr/local/svn/repositories/svn/db: Cannot allocate memory [Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] Could not fetch resource information. [500, #0] [Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] Could not open the requested SVN filesystem [500, #160029] [Wed Apr 07 04:26:10 2004] [error] [client 212.151.130.227] (17) File exists: Could not open the requested SVN filesystem [500, #160029]
這一般表示Berkeley DB版本庫用光了全部數據庫鎖(FSFS版本庫不會出現這種狀況)。一般的運行過程當中不該該出現這種狀況,若是確實出現了,解決辦法是用本文中描述的方法來恢復數據庫。若是這種狀況時常發生,你極可能應該提升db/DB_CONFIG文件中鎖設置(set_lk_max_locks、set_lk_max_lockers和set_lk_max_objects)的默認值。改變已存在的版本庫的DB_CONFIG配置後,記得恢復數據庫。
你的工做拷貝沒有壞掉,數據也沒有丟失。Subversion的工做拷貝是一個日誌系統,全部的操做在執行以前都被記錄在日誌中。若是svc客戶端程序被強制停止(段錯誤或殺進程,不包括Control-C),會有多個文件鎖遺留下來,記錄了未完成的操做。('svn status'命令會在被鎖定的目錄後顯示'L'。)其餘試圖訪問工做拷貝的進程看到這些鎖後會返回操做失敗。想解鎖你的工做拷貝,須要讓svn客戶端完成未完的操做。執行:
svn cleanup working-copy
三種狀況下會出現這個問題
提交失敗致使了你的工做拷貝被破環。
在你提交時,新版本被添加到服務器上,而後你的客戶端執行提交後的管理任務(包括刷新本地拷貝)。在第二個操做以前,你的提交處在一個「過時」的狀態之中。致使這種狀況發生的緣由有,(極少數狀況下)數據庫一端出現了問題,(大多數狀況下)網絡在錯誤的時間中斷了。
這時,極可能你的提交已經成功了。你能夠執行"svn log -rHEAD"來查看提交是否真的成功了。若是成功了,執行「svn revert」,回退本地修改,而後執行「svn update」來取回你已經提交的修改。(注意,「svn update」能更新你的本地拷貝,而revert不能。)
版本混雜。
提交的時候,在客戶端的工做拷貝中,只有這次提交涉及的節點會被更新,而不是全部節點。這意味着,你最後一次提交決定你的工做拷貝中了文件和目錄的版本號,他們可能不是同一版本。對於像修改目錄屬性等特定操做,若是版本庫中有更新的版本,你的提交會被拒絕,以防止數據丟失。詳細請見版本混雜的侷限在使用Subversion作版本控制中。
執行'svn update'能夠解決這個問題。
你的版本可能確實是過期的 — 即在你提交的時候,有人基於你的上一次改動又做了更新。執行'svn update'來解決這個問題。
若是要往補丁里加入新文件,你可能得使用svn add命令,這樣svn diff命令纔會將新文件包含在補丁裏面。若是你的補丁已經提交到代碼庫裏頭了,而後你運行svn update,這個時候你可能會收到錯誤提示:「svn:Failed to add file ‘my.new.file’。object of the same name already exists」(不能增長「my.new.file」,同名文件已經存在)。
之因此會產生這個錯誤是由於你的工做拷貝中已經有這個文件了。解決這個問題的步驟以下:
你可能須要把版本庫中的新文件和你的本地的文件作一下比較。
Subversion使用了插件系統來訪問版本庫。如今支持三個插件:ra_local支持訪問本地版本庫,ra_dav支持經過WebDAV訪問版本庫,ra_svn支持經過svnserver服務器訪問遠程或本地的版本庫。當你執行Subversion的操做時,會根據URL scheme來決定加載哪個插件。以`file://'開頭的URL會加載ra_local,`http://'開頭的URL會加載ra_dav。
你看到的錯誤是說沒法找到正確的插件。發生這個問題,一般是由於你將Subversion的庫文件編譯成動態庫後,卻沒有執行'make install'。或者雖然你執行了'make install',可是操做系統仍是找不到Subversion的動態庫所在的路徑。在Linux系統中,你能夠把相應的路徑加入到/etc/ld.so.conf中,而後運行ldconfig。若是你不想這麼做,又或者你沒有root權限,你能夠在LD_LIBRARY_PATH中指定相應的路徑。
參考這個FAQ條目。
可能你係統裏的/usr/local/bin/apr-config和/usr/local/bin/apu-config太舊了。刪了它們,更新apr/和apr-util/,使其和你編譯的版本保持一致,再從新編譯。
可能你須要最新版本的platform SDK,VC++ 6.0帶的SDK太舊了。
像這樣:
svn import file:///d:/some/path/to/repos/on/d/drive
更多細節請見Subversion書中的版本庫URL。
VS.Net有一個ASP.Net子系統,它使用WebDAV來經過IIS來遠程發佈。這個子系統剔除了全部以"."開頭的目錄。在你試圖遠程發佈你的工做目錄的時候,".svn"將致使問題。錯誤信息相似"unable to read project information"。
要想繞過這個問題,設置環境變量SVN_ASP_DOT_NET_HACK爲任意值 — 這將告訴Windows clients在你的工做拷貝中使用"_svn"做爲目錄名。參見Subversion 1.3發佈說明的相關章節來取得更多信息,參見這個問題來用其餘方法配置管理目錄名。
例如,有用戶反映,經過本地協議訪問的,導入功能正常工做:
$ mkdir test $ touch test/testfile $ svn import test file:///var/svn/test -m "Initial import" Adding test/testfile Transmitting file data . Committed revision 1.但若是從遠程訪問的話就出錯了:
$ svn import http://svn.sabi.net/test testfile -m "import" nicholas's password: xxxxxxx svn_error: #21110 : <Activity not found> The specified activity does not exist.
咱們曾經遇到過這樣的問題,當httpd進程對REPOS/dav/目錄沒有可寫權限的時候會發生。你須要檢查一下相關的權限問題,確保Apache可以往dav/目錄中寫入東西。(固然還有db/目錄)。
你須要安裝Windows XP的SP1補丁。你能夠在下面這裏找到全部相關的信息:
簡而言之,這是爲你好。
Subversion對保護你的數據很是重視,不僅是你已經版本化的數據。你對已經版本控制的文件所作的修改,或者你即將添加到版本庫中的文件,都必須當心對待。
使用svn revert命令須要很是明確地指定目標—即便目標是‘.’—就是其中一個方面。這個要求(一樣對於--recursive (-R)標記,若是你真的須要遞歸執行某個操做,你也要這樣作)是爲了讓你清楚的知道你要作的事情,由於一旦你執行了撤銷工做拷貝修改的命令,全部本地的修改都會永遠消失。
你的apr-util連接的是DB-3,而svn連接的是DB-4。不幸的是,DB符號並非不相同的。當mod_dav_svn被加載入Apace的進程空間的時候,他會使用apr-util的DB-3庫來解析符號。
解決辦法就是確保apr-util是在DB-4下編譯的。你能夠在編譯的時候指定特定的開關爲apr-util的配置或者apache的配置:「--with-dbm=db4 --with-berkeley-db=/the/db/prefix」。
這確實不是Subversion的問題,但常常會影響Subversion用戶。
隨Red Hat 9還有Fedora發行的Berkeley DB庫依賴於對NPTL的內核支持(本地Posix線程庫)。
Red Hat提供的內核對這方面有內置的支持,但若是你是本身編譯的內核,那麼你可能不會有NPTL的支持。若是是這個緣由的話,那麼你可能會看到以下的錯誤:
svn: Berkeley DB error svn: Berkeley DB error while creating environment for filesystem tester/db: Function not implemented
這個問題能夠按照下面的方法解決:
LD_ASSUME_KERNEL
環境變量是否已經設置爲了2.2.5
,若是是的話,在從新啓動Subversion(Apache)以前刪除此環境變量。(一般只有當你在Red Hat 9上面運行 Wine或者Winex才須要設置這個環境變量)要使用NPTL版本的Berkeley DB,你還須要使用支持NPTL的glibc庫,極可能是i686版本。參考 http://svn.haxx.se/users/archive-2004-03/0488.shtml。
這多是因爲一些監聽文件系統變化的windows服務(如殺毒軟件,索引服務,COM+事件通知服務)。這不屬於Subversion的Bug,因此咱們很難修正這個問題。關於這種狀況的調查說明能夠在這裏找到。在7598版本中,對這個問題作了改進,對於大多數人來講,應該會下降這種狀況出現的概率。若是你使用的是較早的版本,請更新到最新的發行版。
這一般是因爲系統中某些資源不足的緣故形成的。你極可能須要配置一下系統,使其可以從源那裏獲取足夠的資源,如硬盤還有網絡中斷。查閱你的系統說明手冊,找到random(4)還有rndcontrol(8)這幾節,看如何修改。
這意味着你的httpd.conf配置有問題,一般狀況下,當你設置的Subversion虛擬目錄同時存在兩種尋址方式的時候會出現這樣的錯誤。
例如,當你將版本庫放到/www/foo目錄下,可是你又同時設置了你的版本庫的根目錄爲/www,那麼你就麻煩了。當有人請求一個/www/foo/bar文件的時候,apache根本不會知道,對方真正想要尋找的文件,是在根目錄裏下的/foo/bar,仍是經過調用mod_dav_svn模塊從/www/foo版本庫中去把/bar文件給取回來,一般Apache的處理行爲是採起前者的方式,所以就會出現「永久轉移」這樣的錯誤了。
解決這個問題的辦法就是確認你的版本庫路徑不會有重疊,或者存在其餘網絡共享可訪問的路徑裏面。
出現這個問題還有一個可能的緣由,就是在網站根目錄存在一個和版本庫的URL同名的文件(文件夾)。例如,假設你的WEB服務器的根目錄設置在/var/www,你的Subversion版本庫被放置在/home/svn/repo目錄下,而後你在Apache下將該版本庫的URL配置成http://localhost/myrepo。若是你這時又在/var/www下建立了一個myrepo的目錄,那麼一樣會產生301的錯誤。
這個問題極可能是由於Apache服務器的一個已知的bug(存在於2.0.48或者更早期的版本),你能夠在http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25040找到相應的補丁。你也能夠在https://issues.apache.org/jira/browse/SVN-1608 上看有沒有和你說的狀況相似的已反饋的bug。
在環境變量CFLAGS中加入-qlanglvl=extended做爲配置參數,這會使到編譯xls的時候更加靈活,這樣應該不會再出現編譯錯誤了。更詳細的信息請參閱http://svn.haxx.se/dev/archive-2004-01/0922.shtml 及相關的文章。
參考 issue 695. 當前的svn checkout -N命令的實現很是糟糕。它會形成工做拷貝某些條目缺失,但它自己又沒有意識到已經出現了不完整性的問題。很顯然,不少的CVS用戶已經對這種使用方式習覺得常了,可是Subversion的用戶還並不習慣。目前尚未好的辦法解決這個問題,只能讓你本身改變操做的流程:先試着檢出單獨的子目錄,而後再手動嵌入到你的工做拷貝中。
這個錯誤信息在這裏有點誤導人。一般這樣的錯誤是由於Apache沒法正確加載mod_dav_svn.so模塊所依賴的模塊。若是當前Apache是以服務的形式運行的,那麼它的path環境變量和普通用戶的並不相同。請確認libdb4*.dll、intl3_svn.dll、 libeay32.dll還有ssleay32.dll均可以在\Apache\bin或者\Apache\modules目錄中找到。若是沒有找到,你能夠從Subversion的安裝目錄下拷貝一份。
若是這樣還解決不了問題的話,那麼你能夠使用相似Dependency Walker這樣的工具來查看mod_dav_svn.so庫的依賴性,看是否還有還沒有解決的依賴性問題存在。
這些鉤子腳本應該會觸發外部程序的,可是這個觸發過程彷佛並無執行。
當Subversion調用一個鉤子腳本時,它會將全部環境變量都清除乾淨,包括unix下的$Path和windows下的%Path%變量,所以,若是你的腳本要訪問外部程序的話你就必須指定好外部程序的完整路徑。
調試技巧:
若是你正在運行Linux或者Unix操做系統,試一下按照下面的步驟手動運行一下腳本:
注意到傳遞給env程序的第一個參數是一個橫槓,這樣能夠保證環境變量爲空。$ env - ./post-commit /var/lib/svn-repos 1234
當使用一個外部的diff命令時,Subversion會生成一個很是複雜的命令行。第一個參數就是具體的--diff-cmd,而後就是具體的--extensions (儘管使用空白的 --符號時會忽略擴展),或者若是沒有指定--extensions或者--extensions爲空的話,就加上‘-u’參數。第三和第四個參數,Subversion會傳遞一個「-L」還有第一個文件的標籤(例如,「"project_issues.html (revision 11209)」)。第五個和第六個就是另外一個「-L」和第二個文件的標籤。第七和第八個參數分別是第一個和第二個文件的名稱(例如,「.svn/text-base/project_issues.html.svn-base」和「.svn/tmp/project_issues.html.tmp」)。
若是你指定的diff命令不支持這些參數的話,你可能須要建立一個簡單的封裝腳原本忽略這些參數,而後將最後的你須要的文件的路徑參數傳遞給diff命令。
警告:Subversion並不但願外部的diff工具會改變它接收到的文件,不然可能會破壞當前工做拷貝。
更多信息請參考issue #2044.
冷靜一下,深呼吸。
在windows 2000及以後的版本上,svn 1.2以後的版本都使用標準的windows API來加密數據,因此只有用戶本身可以解密出緩存的密碼來。
在Mac OS X, svn 1.4之後的版本使用系統的keychain功能來加密以及存儲svn的密碼。
Subversion 1.6會爲UNIX/Linux處理這個問題,對於GNOME Keyring和KWallet的支持已經實現,均可以方便的在磁盤上存儲加密的密碼。這些程序能夠在運行中的或編譯中添加。若是沒有,客戶端會使用明文緩存密碼,可是它若是以明文存儲咱們會首先詢問是否容許。
Subversion 1.5以及以前的版本在UNIX/Linux中,密碼會以明文形式保存在~/.subversion/auth/中,請注意,雖然是明文存儲(一般是~/.subversion/auth/),可是密碼的訪問許但是700,只有你能夠閱讀。
儘管如此,若是你仍是擔憂的話,那麼你能夠將密碼緩存的功能永久關閉。在svn 1.0的客戶端中,你只須要在你的運行時配置文件設置‘store-auth-creds = no’。對於svn 1.1以及以後的版原本說,你能夠使用粒度更細的設置‘store-passwords = no' (這樣服務器的證書仍是會緩存)。更多關於密碼緩存的信息已經能夠看「日構建」Subversion手冊之中第六章的「客戶端憑證緩存。
最後要說的是,咱們知道CVS不少年來一直都是將緩存的密碼存放在.cvspass文件中的。表面上來看存放在裏面的數據是加密過的,但實際上,他們只是使用很是簡單的算法來進行混淆,就像rot13同樣。這些所謂的密碼能夠很輕易就被破解掉。這種混淆的惟一做用就是防止其餘用戶如管理員意外的看到密碼。可是目前尚未人但願Subversion也這樣作。若是你感興趣的話,你能夠爲其寫補丁而後發送到dev@list。
Berkeley DB 4.1版本至關的不穩定,而4.0和4.2都相對比較穩定。這條錯誤信息就是4.1版本有時候發生問題時的提示信息。
這個問題是因爲使用Berkeley數據庫作支撐的Subversion版本庫中的其中一張表的某個數據庫格式域(database format field)被破壞了。目前還不知道什麼緣由,這一般都是由於「copies」表出錯,致使它從「btree」類型轉換成「recno」類型。你能夠按照下面列舉的簡單的恢復流程來處理。若是下面的步驟未能成功,你應該聯繫Subversion的用戶郵件列表。
早期版本的APR在0.9版本分支上,若是使用Apache 2.0.x和Subversion 1.x,那麼對於大文件是沒有支持的(2Gb以上)。在APR 0.9.5及之後的版本還有Apache 2.0.50及之後的版本中已經考慮到這個問題了,並作了修正。可是這個修正並非針對全部操做系統的,而是隻針對Linux。
在Berkeley DB 4.3以前,svnadmin recover可以適當的將Berkeley DB的版本庫進行升級。可是Berkeley DB 4.3版本中的一個行爲的改變致使瞭如今的升級過程失敗。
使用下面的流程來置換升級你目前基於Berkeley DB 4.3及以後版本之上的版本庫:
如今版本庫應該可以在Berkeley DB 4.3上正常使用了。
注意,這裏假設版本庫是運行在Apache 2.0.x之上。
APR 0.9.6 有個bug,當運行在Tiger上的時候會存在,當你嘗試檢出一個大於64KB的文件時會出現這個錯誤。這會致使檢出失敗,一般給出的錯誤信息都是不可預料的。下面是可能會出現的提示信息,你看到的可能不大同樣。
svn: Invalid diff stream: [tgt] insn 1 starts beyond the target view position
svn: Unexpected end of svndiff input
svn: REPORT request failed on '/path/to/repository' svn: REPORT of '/path/to/repository/!svn/vcc/default': Chunk delimiter was invalid
一樣,在Apache的error_log日誌中也會記錄相應的錯誤,如:
[error] Provider encountered an error while streaming a REPORT response. [500, #0] [error] A failure occurred while driving the update report editor [500, #190004]
爲了確認這個bug是否存在—假設你能夠訪問版本庫所在的機器—嘗試使用File://的方式來檢出,這樣就能夠繞過Apache直接經過文件系統來訪問了。若是這樣檢出成功的話,那麼問題就出在上面提到的bug上。
目前最好的解決方案就是升級到APR 1.2.0+。
或者你也能夠從各自的源裏從新編譯Apache還有Subversion,在運行Apache配置前先設置好相應的環境變量。
setenv ac_cv_func_poll no
或者以Bourne shell 的語法,以下:
ac_cv_func_poll=no; export ac_cv_func_poll
若是你分別編譯APR / APRUTIL(例如,你並不想使用Apache發行包中的某些部分),你必須在配置APR以前設置好環境變量,由於這就是問題所在。
若是你在編譯Subversion主線源代碼的最後一步出現了下面的錯誤:
/usr/local/apache2/lib/libaprutil-0.so.0: undefined reference to `db_create' /usr/local/apache2/lib/libaprutil-0.so.0: undefined reference to `db_strerror'
那極可能是因爲你使用的是Debian系統,你須要升級你的‘libtool’。(我據說Debian的打包者不得不作了一些小的改動來修正一些錯誤。這可能會致使Subversion編譯的時候出現問題。但這只是猜想,在寫這個FAQ條目的時候我並無時間去驗證一下細節的東西。你能夠查看http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=112617 還有相關的帖子獲得更詳細的討論。)
無論怎麼樣,若是你在2005年11月15號的時候在Debian GNU/Linux系統上面運行最新的testing發行版,而後遇到這個問題,那麼解決方法就是,將libtool 1.5.20的源代碼使用標準的「./configure && make && sudo make install」從新編譯,再對工做拷貝執行了一次「make clean」的清理,而後運行「./autogen.sh」, 「./configure」,「make」,最後一切都正常了。
注意,有一個相似的反饋也已經發布在 http://svn.haxx.se/dev/archive-2003-01/1125.shtml,可是在上面卻沒有提到這個解決方案。
一句話歸納:使用--listen-host=0.0.0.0參數調用svnserveShort。
再具體一點,FreeBSD的守護進程默認狀況下只監聽tcp6。上面這個選項用來啓用tcp4的監聽。
那是由於你要添加的目錄已經包含了.svn的目錄了 — 它已是工做拷貝了 — 但那個目錄是來自其餘的版本庫中而不是你當前正在訪問的版本庫。這種現象極可能就是由於你使用了操做系統的拷貝功能直接從另一個工做拷貝上覆制(沒有使用svn copy)該目錄到當前工做拷貝中。
比較快可是有些不雅的解決方案就是刪除你以前複製的文件夾下全部的.svn目錄,而後add命令就能夠順利執行了。若是你使用的是Unix,你能夠使用下面的命令:
find dir -type d -name .svn -exec rm -rf {} \;
然而,若是工做拷貝來自同一個版本庫,直接刪除或移走工做拷貝,而後經過svn copy得到一個正確的拷貝也比較理想,能夠節省版本庫的空間。
若是來自不一樣的版本庫,你應當問本身爲何要做這個拷貝;你應該確保經過添加目錄,你不會在版本庫中作出非預期的拷貝。
當編譯APR時使用/dev/random設備,服務器沒有辦法獲取足夠的內存量的時候這個問題常常會出現。若是服務器上只有Subversion在使用APR,那麼你能夠安全的從新編譯APR,編譯的時候帶上參數 --with-devrandom=/dev/urandom 。固然,若是有其餘進程在使用APR的時候,那麼你就不能這樣來作了,不然會形成其餘服務不安全。
這個錯誤多是因爲OpenSSL 0.9.8版本的問題。你能夠下載早期不存在此問題的版本(或者可能的話,升級到更新的版本)。
svn: This client is too old to work with working copy '/path/to/your/working/copy'; please get a newer Subversion client這是由於Subversion工做拷貝的格式發生了不兼容的改動—新版本的Subclipse對你的工做拷貝作了升級,因此你的命令行客戶端程序,由於是版本比較老的,所以沒法讀取其內容。(這個問題並不僅是存在於Subclipse上,也有多是當你同時使用另一個1.4之後的新版本的時候,舊版本的程序也會出現相似的問題)你能夠簡單的把你的命令行客戶端升級到1.4及以後的版本。 對於Subversion 1.5,提供了一個降級工做拷貝到較早版本的輔助腳本;見 這個FAQ。
有時候,工做拷貝中包含了一些未被歸入版本控制的文件,這個時候svn switch就會發生錯誤。switch的過程就會中止,這會致使工做拷貝一半被switch,另外一半卻保持原樣。
不幸的是,若是這個時候你採起的措施不正確的話,那麼你的工做拷貝將會不能使用。有時候,svn會提示用戶執行清理(svn cleanup)。但清理命令又有可能形成錯誤。參考:issue #2505。
用戶能夠手動的刪除那些形成問題的文件或目錄,而後再執行清理命令,接着繼續swich,這樣即可以恢復。
注意,對從版本庫中檢出的原始副本進行switch一般不會發生錯誤。若是你正在開發過程當中須要使用到svn switch命令,那麼有3種方式能夠使用:
# Check and delete svn unversioned files: svn status --no-ignore | grep '^[I?]' | sed 's/^[I?]//' svn status --no-ignore | grep '^[I?]' | sed 's/^[I?]//' | xargs rm -rf
在 issue 2505 中有更詳細的例子。這個問題的產生是由於svn客戶端爲了保險起見,不會直接刪除全部未被版本控制的文件。
下面還有兩個更具體的例子描述了相似的問題。還有其餘的svn switch錯誤在這裏沒有說起,你只有在從一個乾淨檢出的工做拷貝中執行swich才能避免。
wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx svn: Won't delete locally modified directory '<dir>' svn: Left locally modified or unversioned files
刪除全部未被版本控制的文件,而後繼續切換過程,這樣能夠恢復。
wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx svn: Won't delete locally modified directory '<dir>' svn: Left locally modified or unversioned files
在這種狀況下,刪除未被版本控制的文件並不能恢復,執行cleanup的時候會出錯,可是svn switch會提示你去執行svn cleanup。
wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx svn: Directory '<dir>/.svn' containing working copy admin area is missing wc/$ svn cleanup svn: '<dir>' is not a working copy directory wc/$ svn switch $SVNROOT/$project/branches/$ticket-xxx svn: Working copy '.' locked svn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)
刪除目錄(還有其餘全部未被版本控制的文件,這樣能夠避免轉換命令不會再重複出現相似的錯誤。而後繼續轉換的過程,這樣能夠恢復。
TortoiseSVN的cleanup錯誤有一點不一樣,你可能會遇到下面的錯誤:
Subversion reported an error while doing a cleanup! <dir>/<anotherdir> is not a working copy directory
在這裏講到的每個例子中,svn switch命令會失敗,使到你的工做拷貝變成只有一半發生轉換成功的,svn status會顯示出全部發生轉換的文件,用S標記出來(在根目錄看到的狀況可能有所不一樣),用!標記出發生問題的目錄,~標記出出錯的問題文件(可能還有L用來標記鎖定的文件),就像下面列舉的同樣:
wc/$ svn status ! . ! <dir> S <switched_things> ~ <dir>/<thing_that_is_now_unversioned>
仔細研究了windows關於文件命名的API文檔才發現形成這一問題的最多見緣由。簡單的說,當你使用unicode版本的windows和路徑相關的函數時,你能夠指定的路徑長度比較長,並且提供了絕對路徑定位,而不是相對路徑定位。幸運的是Subversion使用的Apache Portable Runtime(APR)庫透明的對這種絕對路徑(如C:\WorkingCopy\file.txt)進行了轉換,將其轉換成符合windows API要求的格式(\\?\C:\WorkingCopy\file.txt),這種轉換也能夠反向。不幸的是,你只有在使用絕對路徑的時候才享用了這些長路徑的好處。
要查看路徑長度是否是形成你所遇到的問題,你能夠在Subversion命令行客戶端下使用絕對路徑代替相對路徑(或者根本不提供路徑參數)。換句話說,若是你原先是這麼作的:
C:\> svn up WorkingCopy
或者這樣作的:
C:\> cd C:\WorkingCopy C:\WorkingCopy> svn up
把它改爲下面這樣的方式
C:\> svn update C:\WorkingCopy
若是問題解決了,那麼恭喜你——你已經成功突破了windows的路徑長度限制,而且如今你已經知道怎麼解決這個問題了。
爲何這個問題不會影響TortoiseSVN呢? 由於TortoiseSVN對SubversionAPI提供的永遠都是絕對路徑。
那爲何Subversion命令行客戶端不是永遠都把輸入轉換成絕對路徑,而後使用絕對路徑呢?Subversion的開發者在開發的時候基於一個原則,那就是出於對用戶體驗的考慮,在工具的輸出中顯示的路徑必須匹配輸入的路徑的語法。若是輸入的相對路徑轉換到絕對路徑沒有太多價值的話,那麼這個轉換出於複雜性考慮就去掉了。(換句話說,這是一個比較難的問題,但不是一個比較迫切的問題)。
有時候在次版本改動的發行包下,工做拷貝中的元信息格式也會發生不兼容的改變。例如,假設你使用Subversion1.4.4建立了一個工做拷貝,但有一天你升級到1.5.0版本。但後來你又想將其改爲1.4.4,這個時候就出錯了——提示信息就如你所描述的。
這是由於1.5.0將你的工做拷貝升級到能夠支持新特性的格式(例如,修改列表,keep-local標誌,variable-depth目錄)儘管1.4.4並不知道任何這些特性,但它可以識別出來,工做拷貝里面使用的格式已經被升級到一個新的它不能支持的版本。
1.5.0升級工做拷貝是出於一個好的緣由,那就是它知道1.4.4如今並不瞭解工做拷貝的任何元信息,所以若是讓1.4.4的版本去幹擾工做拷貝中的元數據,那麼重要的信息可能會丟失,頗有可能會形成破壞(例如你能夠參考issue #2961)。
可是這種自動升級的行爲在當你想要嘗試一個新版本可是又不想永久安裝時,挺讓人討厭的。出於這一點的考慮,咱們發佈了一個腳本,用來安全的對工做拷貝進行版本降級。你能夠在下面的地址下載到:
http://svn.collab.net/repos/svn/trunk/tools/client-side/change-svn-wc-format.py
使用--help參數調用此腳本,能夠查看怎麼腳本的運行幫助。將來Subversion新版本發佈時,咱們會盡可能更新這個FAQ條目,使他覆蓋到更多的降級的場景。
Neon庫,是用來做爲Subversion服務器和HTTP客戶端進行通信的庫,一般被編譯成靜態庫。可是它後來被連接到不一樣的動態連接庫中,這會致使在AMD 64位操做系統系統上面編譯的過程出現錯誤,出現相似下面的信息:
subversion-1.4.6/neon/src/.libs/libneon.a(ne_request.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC /home/jrandom/subversion/subversion-1.4.6/neon/src/.libs/libneon.a: could not read symbols: Bad value
在開發者郵件列表中有一篇文章提到了這一點。
解決方法就是爲Subversion的配置腳本提供一個「--enable-shared」的參數。
簡而言之,這個錯誤表明了一類問題,也就是Apache認爲Subversion的客戶端不會再處理它創建的網絡鏈接。取決因而否使用SSL,或者Apache什麼時候決定中斷鏈接,相似情形也會報告一些其餘的錯誤信息,
Subversion客戶端保證工做拷貝永遠處於正常狀態,一個方法是會臨時保存全部檢出文件的全部原始版本,直到得到給定目錄的全部文件和子目錄。一旦目錄的數據被下載,客戶端會整理目錄,並將將文件的原始版本複製回工做區域,做爲管理數據等等。在這個目錄整理過程當中,客戶端會關注這些任務而不會去關心網絡鏈接。有時候 —一般是版本化目錄包含大量文件,或者很是大的文件—客戶端會在整理目錄(無論網絡傳輸流)上花費大量時間,因此Apache會認爲客戶端已經永遠離開了,所Apache關閉了網絡傳輸流,而後客戶端發現服務器放棄了鏈接,並報告了這樣的錯誤。
一個辦法是增長Apache一直等待客戶端還在監聽網絡流的最長時間,你能夠修改Apache的Timeout配置參數。你也應該注意一下你的數據集。若是你一個目錄有大量的文件,就會更容易致使這個問題。若是你能將一組文件分配到一些目錄中,將會對你們都有益。
若是將Subversion的測試數據保存在RAM磁盤上,那麼測試的過程將會變得很是快。在Linux系統上,你能夠直接將RAM磁盤掛載:
mount -t tmpfs tmpfs /path/to/src/subversion/tests/cmdline/svn-test-work -o uid=$USER,mode=770,size=32m
或者,若是要更長期的掛載,能夠將下面這一行添加到你的/etc/fstab
文件中:
tmpfs /path/to/src/svn/subversion/tests/cmdline/svn-test-work tmpfs defaults,user,noauto,exec,size=32m
RAM磁盤空間至少爲大約700MB。儘管如此,你仍是能夠經過清理測試目標來大大下降空間需求(在上面的配置例子中咱們已經看到了)還有你的內存佔用。清理意味着佔用更多的IO資源,可是因爲測試數據仍是存在於內存中的,所以不會形成任何性能的降低。
make check CLEANUP=true
參考 http://svn.haxx.se/dev/archive-2003-02/0068.shtml 能夠看到更多關於RAM磁盤使用的權威討論。
在往unix-y系統上運行make install這一步以前,動態編譯Subversion源代碼實際上執行的是libtool-generated腳本,這個腳本會從新連接而且運行真正的二進制文件,就以下面顯示的同樣,這會讓調試更加複雜:
subversion$ gdb subversion/svn/svn
... "/path/to/subversion/subversion/svn/svn": not in executable format: File format not recognized
若是編譯的時候使用--disable-shared
參數來配置使用靜態連接到二進制庫,或者從新安裝而後將調試器指向新安裝的版本,這樣可能能解決一部分問題,可是常常咱們須要在源代碼中臨時直接的進行調試。
要作到這一點,在shell腳本中編輯上一次執行的語句,而後在你的調試器中運行真正的二進制庫。在gdb中,就是將exec "$progdir/$progname"
替換exec gdb --args "$progdir/$progname"
。
這個小技巧在使用libtool-generated的shell腳本進行白盒測試的時候中很是有用。
默認狀況下,gcc會常常優化那些私有變量及函數,還有相關的操做。這樣會形成調試的時候跟進一段代碼變得更復雜。
unix-y systems上的解決辦法就是在make這一步的時候將這個優化過程關閉。
subversion$ make EXTRA_CFLAGS=-O0
(那是一個橫槓加兩個字母的O)。你也能夠經過運行下面的配置使到此配置應用到之後全部的調試過程當中:
subversion$ ./configure --enable-debug
對於產品的安裝來講,要記住在從源碼安裝Subversion時撤銷這個操做,你能夠經過從新運行make或者configure並不附加任何參數來撤銷上面的修改操做。
Subversion 客戶端使用WebDAV/DeltaV 協議的一個子集來做爲 mod_dav_svn server 模塊的一部分。簡而言之:
OPTIONS, PROPFIND, GET, REPORT, MKACTIVITY, PROPPATCH, PUT, CHECKOUT, MKCOL, MOVE, COPY, DELETE, LOCK, UNLOCK, MERGE
關於協議的細節問題能夠在下面這個連接找到相應的文檔:
http://svn.collab.net/repos/svn/trunk/notes/webdav-protocol參閱 Poul-Henning Kamp的關於freebsd-hackers的帖子:http://www.freebsd.org/doc/en_US.ISO8859-1/books/faq/misc.html#BIKESHED-PAINTING.
Jim Blandy設計了Subversion的名字和版本庫的設計,把「Subversion」讀做 「Subversion」。
在Subversion的源代碼中有不少引用指向‘baton’對象。他們只是一些對象。有不少void *的數據結構做爲某個函數的上下文。在另一些API裏,他們一般經過void *ctx或者void *userdata來調用的,就像Subversion的開發者經過「batons」數據結構來調用同樣,可是更省資源。