Subversion安裝成service
之前的svnserve要想成爲windows服務,必須依賴於svnservice或其餘工具。從Subversion1.4開始,Subversion自己就集成Windows服務的工具。web
1,安裝svnservice
在Windows NT中(包括Windows XP, Windows 2000, Windows 2003 Server)自己包含了一個安裝服務的工具,叫作"Service Control",也就是sc.exe。數據庫
例如個人Subversion安裝在"D:\Subversion",版本庫在"D:\svnroot",而我但願對應的Subversion服務名爲svnservice,安裝這個svn服務的命令就能夠這樣寫:windows
sc create svnservice binpath= "D:\Subversion\bin\svnserve.exe --service -r D:\svnroot" displayname= "SVNService" depend= Tcpip |
請注意,由於便於察看,上面的命令分爲多行,但在實際執行時應該在一行裏。另外,在之前啓動svnserve時會使用"-d"選項,也就是守護進程模式,在這裏不能使用,會致使服務沒法啓動。一樣,"-i"和"-t"選項也不能使用。緩存
在命令行窗口執行完這個命令以後,服務尚未啓動,你能夠繼續運行"net start svnservice"啓動這個服務,而後使用"net stop svnservice"中止服務。安全
另外還有兩點須要當心處理。首先,若是路徑中包括空格,必定要用「\」處理「"」號,例如上面的例子中若是svnserve.exe在「c:\program files\subversion\」中,則命令應該寫爲「binpath= "\"c:\program files\subversion\bin\svnserve.exe\"」(「」中的內容),整個命令以下,紅色部分是改變部分:服務器
sc create svnservice binpath= "\"D:\program files\Subversion\bin\svnserve.exe\" --service -r D:\svnroot" displayname= "SVNService" depend= Tcpip |
其次,sc對選項的格式還有要求,例如「depend= Tcpip」不能寫爲「depend = Tcpip」或「depend=Tcpip」,也就是「=」前不能有空各,然後面必須有空格。oracle
2,刪除服務
若是服務安裝的有問題,你可能須要刪除服務。要刪除前面添加的服務,只須要運行"net start svnservice","svnservice"就是咱們建立服務時使用的名字。ide
3,配置服務是自動啓動
默認狀況下安裝的服務不會隨Windows的啓動而啓動,爲了使svn服務可以隨Windows啓動而啓動,須要修改一下"sc create"命令(首先要刪除),增長"start= auto"選項:svn
sc create svnservice binpath= "D:\Subversion\bin\svnserve.exe --service -r D:\svnroot" displayname= "SVNService" depend= Tcpip start= auto |
固然你也可使用圖形化的工具修改服務的屬性,你能夠在「開始->運行...」中執行"services.msc",而後在界面中修改。工具
Subversion的權限控制
1,認證(Authentication)和受權(Authorization)
這兩個術語常常一塊兒出現。其中認證的意思就是鑑別用戶的身份,最多見的方式就是使用用戶名和密碼,受權就是判斷用戶是否具有某種操做的權限,在Subversion裏提供了「authz-db」文件,實現了以路徑爲基礎的受權,也就是判斷用戶是否有操做對應路徑的權限,在Subversion 1.3以後,svnserve和Apache同樣均可以使用「authz-db」文件。
2. svnserve下的配置文件
由於本文是以svnserve爲例的,因此先介紹一下版本庫目錄的結構:
D:\SVNROOT\PROJECT1 ├─conf ├─dav ├─db │ ├─revprops │ ├─revs │ └─transactions ├─hooks └─locks |
其中conf下面有三個文件:
authz passwd svnserve.conf |
其中的「svnserve.conf」是這個版本庫的配置文件,當使用svnserve時,這個配置文件決定了使用什麼認證和受權文件:
password-db = passwd authz-db = authz |
上面的配置說明使用「svnserve.conf」同目錄的passwd和authz,其中的password-db指定了用戶密碼文件,authz-db是咱們的受權文件,也就是咱們本文主要介紹的文件。
注意:使用Apache做爲服務器時,根本就不會參考「svnserve.conf」文件的內容,而是會參考Apache的配置。
3,基於svnserve的版本庫文件佈局
使用svnserve時,爲了管理的方便,應該使用相同的認證和受權文件,因此應該讓全部版本庫的配置文件svnserve.conf指向同一個password-db和authz-db文件。下面是一個多版本庫的目錄:
D:\SVNROOT ├─project1 │ ├─conf │ ├─dav │ ├─db │ │ ├─revprops │ │ ├─revs │ │ └─transactions │ ├─hooks │ └─locks └─project2 ├─conf ├─dav ├─db │ ├─revprops │ ├─revs │ └─transactions ├─hooks └─locks |
D:\SVNROOT下有兩個目錄project1和project2,都已經建立了版本庫,因此咱們修改每一個conf目錄下的svnserve.conf,使之指向同一個password-db和authz-db文件。
password-db = ..\..\passwd
authz-db = ..\..\authz這樣,D:\SVNROOT\passwd和D:\SVNROOT\authz就控制了全部版本庫的svnserve訪問。另外在後面的操做中要關閉匿名訪問,應該去掉「anon-access = none」前的「#」號,保證只有認證用戶能夠訪問。
注意:還有一點須要注意,那就是svnserve的「realm」的值,在上面的設置下,應該保證全部的版本庫使用相同的realm值,這樣,對版本庫的密碼緩存能夠在多個版本庫之間共享,更多細節見客戶端憑證緩存。
4,測試用戶和組說明
版本庫禁止任何匿名用戶的訪問,只對認證用戶有效。
root:配置管理管理員,對版本庫有徹底的管理權限。
p1_admin1:project1的管理員,對project1有徹底權限。
p1_d1:project1的開發者,對project1的trunk有徹底的權限,可是對其中的/trunk/admin目錄沒有任何權限。
p1_t1:project1的測試者,對project1的trunk有徹底的讀權限,可是對其中的/trunk/admin目錄沒有任何權限。
p2_admin1:project2的管理員,對project2有徹底權限。
p2_d1:project2的開發者,對project2的trunk有徹底的權限,可是對其中的/trunk/admin目錄沒有任何權限。
p2_t1:project2的測試者,對project2的trunk有徹底的讀權限,可是對其中的/trunk/admin目錄沒有任何權限。
對應的組及組的用戶:
p1_group_a:p1_admin1 p1_group_d:p1_d1 p1_group_t:p1_t1 p2_group_a:p2_admin1 p2_group_d:p2_d1 p2_group_t:p2_t1 |
5,修改D:\SVNROOT\passwd文件
前面已經說過了,用戶和密碼文件應該是在D:\SVNROOT\passwd,因此咱們爲每一位用戶設置權限,文件內容以下:
[users] p1_admin1 = p1_admin1 p1_d1 = p1_d1 p1_t1 = p1_t1 p2_admin1 = p2_admin1 p2_d1 = p2_d1 |
p2_t1 = p2_t1爲了便於驗證,全部密碼和用戶名一致,若是你使用的是其餘認證方式,這一步可能不一樣,可是用戶名應該都是同樣的。
6,配置受權,修改D:\SVNROOT\authz
[groups] p1_group_a = p1_admin1 p2_group_a = p2_admin1 [/] [project1:/] [project1:/trunk/admin] [project2:/] [project2:/trunk/admin] |
通過以上設置之後,你會發現一些有趣的事情。當使用用戶「p1_d1」,檢出project1的trunk時,目錄是空的,好像admin目錄根本不存在同樣,當使用p1_d1用戶瀏覽版本庫時,可以看到admin目錄,可是其中的內容卻沒法看到。
關於中文目錄,也是沒有問題的,只是注意要把authz文件轉化爲UTF-8格式,在個人WINXP的UltraEdit裏顯示的文件格式爲U8-DOS,具體的作法是用UltraEdit打開authz文件,而後選擇「文件->轉換->ASCII轉UTF-8」,而後保存。
再複雜的狀況也不過如此,在實際的工做中要首先規劃好權限,只賦給用戶最小的權限,保證以最小的配置實現最複雜的權限控制。
Subversion備份
版本控制最關鍵的一件事是保證數據的安全性,不能由於磁盤損壞,程序故障形成版本庫無可挽回的錯誤,爲此必須制定較完備的備份策略。在Subversion中,咱們有三種備份方式:徹底備份,增量備份和同步版本庫。
1, 徹底備份
最多見和簡單的備份就是直接使用拷貝命令,將版本庫目錄拷貝到備份目錄上,就能夠了。可是這樣不是很安全的方式,由於若是在拷貝時版本庫發生變化,將會形成備份的結果不夠準確,失去備份的做用,爲此Subversion提供了「svnadmin hotcopy」命令,能夠防止這種問題。
還記得咱們的版本庫目錄嗎?
D:\SVNROOT ├─project1 │ ├─conf │ ├─dav │ ├─db │ │ ├─revprops │ │ ├─revs │ │ └─transactions │ ├─hooks │ └─locks └─project2 ├─conf ├─dav ├─db │ ├─revprops │ ├─revs │ └─transactions ├─hooks └─locks |
若是要把project1備份到d:\svnrootbak目錄下,只須要運行:
svnadmin hotcopy d:\svnroot\project1 d:\svnrootbak\project1
可是咱們做爲配置管理員,必須想辦法優化這個過程,若是咱們這個目錄下有許多版本庫,須要爲每一個版本庫寫這樣一條語句備份,爲此我寫了下面的腳本,實現備份一個目錄下的全部版本庫。咱們在D:\SVNROOT下建立了兩個文件,simpleBackup.bat:
@echo 正在備份版本庫%1......
@%SVN_HOME%\bin\svnadmin hotcopy %1 %BACKUP_DIRECTORY%\%2
@echo 版本庫%1成功備份到了%2!
這個文件僅僅是對「svnadmin hotcopy」的包裝,而後是backup.bat:
echo off
rem Subversion的安裝目錄
set SVN_HOME="D:\Subversion"
rem 全部版本庫的父目錄
set SVN_ROOT=D:\svnroot
rem 備份的目錄
set BACKUP_SVN_ROOT=D:\svnrootbak
set BACKUP_DIRECTORY=%BACKUP_SVN_ROOT%\%date:~0,10%
if exist %BACKUP_DIRECTORY% goto checkBack
echo 創建備份目錄%BACKUP_DIRECTORY%>>%SVN_ROOT%/backup.log
mkdir %BACKUP_DIRECTORY%
rem 驗證目錄是否爲版本庫,若是是則取出名稱備份
for /r %SVN_ROOT% %%I in (.) do @if exist "%%I\conf\svnserve.conf" %SVN_ROOT%\simpleBackup.bat "%%~fI" %%~nI
goto end
:checkBack
echo 備份目錄%BACKUP_DIRECTORY%已經存在,請清空。
goto end
:end
你在使用的時候,只須要修改backup.bat開頭的三個路徑,將兩個腳本拷貝到「SVN_ROOT」下就能夠了。根據以上的配置,你只須要運行backup.bat,就能夠把「SVN_ROOT」下的版本庫都備份到「BACKUP_SVN_ROOT」裏,而且存放在備份所在日的目錄裏,例如「D:\svnrootbak\2006-10-22」。
雖然這部分工做很簡單,但是必須有人定時地去執行這個操做(例如每週一凌晨),爲了不發生遺忘的狀況,咱們能夠將這個操做加入到系統的at任務當中去,例如仍是上面的環境,爲了安裝at任務,咱們運行:
at 1:00 /every:M D:\svnroot\backup.bat這樣在每週一凌晨1:00都會執行這個備份過程。固然備份在本機也是不安全的,你也許須要上傳到別的機器,這個就要靠你本身去實現了。
2, 增量備份
儘管徹底備份很是簡單,可是也是有代價的,當版本庫很是巨大時,常常進行徹底備份是不現實的,也並沒必要要,可是一旦版本庫在備份之間發生問題,該如何呢,這裏咱們就用到了增量備份。
增量備份一般要與徹底備份結合使用,就像oracle數據庫的歸檔日誌,記錄着每次Subversion提交的變化,而後在須要恢復時可以回到最新的可用狀態。在咱們這個例子中咱們使用的是,svnadmin dump命令進行增量的備份,使用方法是:
svnadmin dump project1 --revision 15 --incremental > dumpfile2
上面的命令實現了對修訂版本15進行增量的備份,其中的輸出文件dumpfile2只保存了修訂版本15更改的內容。
爲了記錄每次提交的結果,咱們須要使用一項Subversion的特性--鉤子(hook),看看咱們的project1目錄:
├─project1 │ ├─conf │ ├─dav │ ├─db │ │ ├─revprops │ │ ├─revs │ │ └─transactions │ ├─hooks │ └─locks |
其中的hooks目錄裏存放的就是鉤子腳本,咱們在此處只使用post-commit鉤子,這個鉤子會在每次提交以後執行,爲了實現咱們的備份功能,咱們在hooks下創建一個文件post-commit.bat,內容以下:
echo off set SVN_HOME="C:\Program Files\Subversion" set SVN_ROOT=D:\svnroot set UNIX_SVN_ROOT=D:/svnroot set DELTA_BACKUP_SVN_ROOT=D:\svnrootbak\delta set LOG_FILE=%1\backup.log echo backup revision %2 >> %LOG_FILE% for /r %SVN_ROOT% %%I in (.) do if D:/svnroot/%%~nI == %1 %SVN_ROOT%\%%~nI\hooks\deltaBackup.bat %%~nI %2 goto end :end |
經過這個腳本,能夠實現D:\svnroot下的版本庫提交時自動增量備份到D:\svnrootbak\delta(肯定這個目錄存在),其中使用的deltaBackup.bat其實能夠放在任何地方,只是對腳本的svnadmin dump的包裝,內容以下:
@echo 正在備份版本庫%2......
%SVN_HOME%\bin\svnadmin dump %SVN_ROOT%\%1 --incremental --revision %2 >> %DELTA_BACKUP_SVN_ROOT%\%1.dump
@echo 版本庫%2成功備份到了%3!
以上兩個腳本能夠直接拷貝到project2的hooks目錄下,不須要修改就能夠實現project2的自動備份。
以上的操做已經OK了,如今須要作的是將徹底備份和增量備份結合起來,也就是在徹底備份後清理增量備份的結果,使之只保存徹底備份後的結果。
當果然出現版本庫的故障,就要求咱們實現版本庫的恢復操做了,這是用要使用svnadmin load命令,同時也須要上次的徹底備份例如要把上次徹底備份backuprepo,和以後的增量備份dumpfile:
svnadmin load backuprepo < dumpfile
最後的結果,能夠下載svnroot.rar,將之解壓縮到d:\下,而後修改幾個bat文件的SVN_HOME就可使用了。
3, 版本庫同步
Subversion 1.4增長了同步機制,能夠實現一個版本庫同另外一個版本庫的同步(但好像只是單向的),咱們能夠用來實現版本庫的備份或鏡像。
3.1. 對目標庫初始化
svnsync init svn://localhost/project2 svn://localhost/project1
其中project2是目標的版本庫,而project1是源版本庫。其中的目標版本庫必須爲空,並且必須容許修訂版本屬性的修改,也就是在目標的版本庫的hooks目錄裏添加一個文件pre-revprop-change.bat,內容爲空便可。
3.2. 同步project2到project1
svnsync sync svn://localhost/project2
這時候你update一下你的project2的一個工做拷貝,就會發現有了project1的全部內容。若是project1又有提交,這時候project2的版本庫沒法看到最新的變化,還須要再運行一遍sync操做,這樣才能將最新的變化同步。須要注意的是,目標版本庫只能作成只讀的,若是目標版本庫發生了變動,則沒法繼續同步了。
3.3. 同步歷史屬性的修改
由於同步不會更新對歷史屬性的修改,因此svnsync還有子命令copy-revprops,能夠同步某個版本的屬性。
3.4. 鉤子自動同步
但願在每次提交時同步,則須要在源版本庫增長post-commit腳本,內容以下:
echo off set SVN_HOME="D:\Subversion" %SVN_HOME%\bin\svnsync sync --non-interactive svn://localhost/project2 |
把以上內容存放爲post-commit.bat,而後放到版本庫project1下的hooks目錄下,這樣project1每次提交,都會引發project2的同步。