### 版本庫的創建和配置
創建一個 Subversion 版本庫出乎尋常的簡單。 Subversion 提供的**svnadmin** 工具,有一個執行這個功能的子命令。要建立一個新的版本庫,只需要運行:
~~~
$ svnadmin create /path/to/repos
~~~
這個命令在目錄`/path/to/repos`創建了一個新的版本庫。這個新的版本庫會以修訂版本版本0開始其生命周期,里面除了最上層的根目錄(`/`),什么都沒有。剛開始,修訂版本0有一個修訂版本屬性`svn:date`,設置為版本庫創建的時間。
在 Subversion 1.1中,版本庫默認使用Berkeley DB后端存儲方式來創建。在以后的發行版中這個行為會被改變。不管怎樣,存儲類型可以使用`--fs-type`參數明確說明。:
~~~
$ svnadmin create --fs-type fsfs /path/to/repos
$ svnadmin create --fs-type bdb /path/to/other/repos
~~~
### 警告
不要在網絡共享上創建Berkeley DB版本庫―它不能存在于諸如NFS, AFS或Windows SMB的遠程文件系統中,Berkeley 數據要求底層文件系統實現嚴格的POSIX鎖定語義,幾乎沒有任何網絡文件系統提供這些特性,假如你在網絡共享上使用Berkeley DB,結果是不可預知的――許多錯誤可能會立刻發現,也有可能在幾個月之后才能發現
假如你需要多臺計算機來訪問,你需要在網絡共享上創建FSFS版本庫,而不是Berkeley DB的版本庫。或者更好的辦法,你建立一個真正的服務進程(例如Apache或**svnserve),把版本庫放在**服務器能訪問到的本地文件系統中,以便能通過網絡訪問。詳情請參看[第6章 *配置服務器*]( "第6章配置服務器")
你可能已經注意到了,**svnadmin**命令的路徑參數只是一個普通的文件系統路徑,而不是一個**svn**客戶端程序訪問版本庫時使用的URL。**svnadmin**和**svnlook**都被認為是服務器端工具―它們在版本庫所在的機器上使用,用來檢查或修改版本庫,不能通過網絡來執行任務。一個Subversion的新手通常會犯的錯誤,就是試圖將URL(甚至“本地”`file:`路徑)傳給這兩個程序。
所以,當你運行**svnadmin create**命令后,就會在運行目錄創建一個嶄新的Subversion版本庫,讓我們看一下在這個目錄創建中創建了什么。
~~~
$ ls repos
conf/ dav/ db/ format hooks/ locks/ README.txt
~~~
除了`README.txt`和`format`文件,版本庫目錄就是一些子目錄了。就像Subversion其它部分的設計一樣,模塊化是一個很重要的原則,而且層次化的組織要比雜亂無章好。下面是對新的版本庫目錄中各個項目的簡要介紹:
conf
一個存儲版本庫配置文件的目錄。
dav
提供給Apache和mod_dav_svn的目錄,讓它們存儲自己的數據。
db
你所有的受版本控制數據的所在之處。這個目錄或者是個Berkeley DB環境(滿是數據表和其他東西),或者是一個包含修訂版本文件的FSFS環境。
format
包含了用來表示版本庫布局版本號的整數。
hooks
一個存儲鉤子腳本模版的目錄(還有鉤子腳本本身, 如果你安裝了的話)。
locks
一個存儲Subversion版本庫鎖定數據的目錄,被用來追蹤對版本庫的訪問。
README.txt
這個文件只是用來告訴它的閱讀者,他現在看的是 Subversion 的版本庫。
一般來說,你不需要手動干預版本庫。**svnadmin**工具應該足以用來處理對版本庫的任何修改,或者你也可以使用第三方工具(比如Berkeley DB的工具包)來調整部分版本庫。不過還是會有些例外情況,我們會在這里提到。
### 鉤子腳本
所謂*鉤子*就是與一些版本庫事件觸發的程序,例如新修訂版本的創建,或是未版本化屬性的修改。每個鉤子都會被告知足夠多的信息,包括那是什么事件,所操作的對象,和觸發事件的用戶名。通過鉤子的輸出或返回狀態,鉤子程序能讓工作繼續、停止或是以某種方式掛起。
*默認情況下,鉤子的子目錄中包含各種版本庫鉤子模板。*
~~~
$ ls repos/hooks/
post-commit.tmpl pre-revprop-change.tmpl
post-revprop-change.tmpl start-commit.tmpl
pre-commit.tmpl
~~~
對每種Subversion版本庫支持的鉤子的都有一個模板,通過查看這些腳本的內容,你能看到是什么事件觸發了腳本及如何給傳腳本傳遞數據。同時,這些模版也是如何使用這些腳本,結合Subversion支持的工具來完成有用任務的例子。要實際安裝一個可用的鉤子,你需要在`repos/hooks`目錄下安裝一些與鉤子同名(如 **start-commit**或者**post-commit**)的可執行程序或腳本。
在Unix平臺上,這意味著要提供一個與鉤子同名的腳本或程序(可能是shell 腳本,Python 程序,編譯過的c語言二進制文件或其他東西)。當然,腳本模板文件不僅僅是展示了一些信息―在Unix下安裝鉤子最簡單的辦法就是拷貝這些模板,并且去掉.tmpl擴展名,然后自定義鉤子的內容,確定腳本是可運行的。Windows用文件的擴展名來決定一個程序是否可運行,所以你要使程序的基本名與鉤子同名,同時,它的擴展名是Windows系統所能辨認的,例如`exe`、`com`和批處理的`bat`。
### 提示
由于安全原因,Subversion版本庫在一個空環境中執行鉤子腳本―就是沒有任何環境變量,甚至沒有`$PATH`或`%PATH%`。由于這個原因,許多管理員會感到很困惑,它們的鉤子腳本手工運行時正常,可在Subversion中卻不能運行。要注意,必須在你的鉤子中設置好環境變量或為你的程序指定好絕對路徑。
目前Subversion有已實現了五種鉤子:
`start-commit`
它在提交事務產生前已運行,通常用來判定一個用戶是否有權提交。版本庫傳給該程序兩個參數:到版本庫的路徑,和要進行提交的用戶名。如果程序返回一個非零值,會在事務產生前停止該提交操作。如果鉤子程序要在stderr中寫入數據,它將排隊送至客戶端。
`pre-commit`
在事務完成提交之前運行,通常這個鉤子是用來保護因為內容或位置(例如,你要求所有到一個特定分支的提交必須包括一個bug追蹤的ticket號,或者是要求日志信息不為空)而不允許的提交。版本庫傳遞兩個參數到程序:版本庫的路徑和正在提交的事務名稱,如果程序返回非零值,提交會失敗,事務也會刪除。如果鉤子程序在stderr中寫入了數據,也會傳遞到客戶端。
Subversion的分發版本包括了一些訪問控制腳本(在Subversion源文件目錄樹的`tools/hook-scripts`目錄),可以用來被**pre-commit**調用來實現精密的寫訪問控制。另一個選擇是使用Apache的httpd模塊**mod_authz_svn**,可以對單個目錄進行讀寫訪問控制(見[“每目錄訪問控制”一節]( "每目錄訪問控制"))。在未來的Subversion版本中,我們計劃直接在文件系統中實現訪問控制列表(ACLs)。
`post-commit`
它在事務完成后運行,創建一個新的修訂版本。大多數人用這個鉤子來發送關于提交的描述性電子郵件,或者作為版本庫的備份。版本庫傳給程序兩個參數:到版本庫的路徑和被創建的新的修訂版本號。退出程序會被忽略。
Subversion分發版本中包括**mailer.py**和**commit-email.pl**腳本(存于Subversion源代碼樹中的`tools/hook-scripts/`目錄中)可以用來發送描述給定提交的email(并且或只是追加到一個日志文件),這個mail包含變化的路徑清單,提交的日志信息、日期和作者以及修改文件的GNU區別樣式輸出。
Subversion提供的另一個有用的工具是**hot-backup.py**腳本(在Subversion源代碼樹中的tools/backup/目錄中)。這個腳本可以為Subversion版本庫進行熱備份(Berkeley DB數據庫后端支持的一種特性),可以制作版本庫每次提交的快照作為歸檔和緊急情況的備份。
`pre-revprop-change`
因為Subversion的修訂版本屬性不是版本化的,對這類屬性的修改(例如提交日志屬性`svn:log`)將會永久覆蓋以前的屬性值。因為數據在此可能丟失,所以Subversion提供了這種鉤子(及與之對應的`post-revprop-change`),因此版本庫管理員可用一些外部方法記錄變化。作為對丟失未版本化屬性數據的防范,Subversion客戶端不能遠程修改修訂版本屬性,除非為你的版本庫實現這個鉤子。
這個鉤子在對版本庫進行這種修改時才會運行,版本庫給鉤子傳遞四個參數:到版本庫的路徑,要修改屬性的修訂版本,經過認證的用戶名和屬性自身的名字。
`post-revprop-change`
我們在前面提到過,這個鉤子與`pre-revprop-change`對應。事實上,因為多疑的原因,只有存在`pre-revprop-change`時這個腳本才會執行。當這兩個鉤子都存在時,`post-revprop-change`在修訂版本屬性被改變之后運行,通常用來發送包含新屬性的email。版本庫傳遞四個參數給該鉤子:到版本庫的路徑,屬性存在的修訂版本,經過校驗的產生變化的用戶名,和屬性自身的名字。
Subversion分發版本中包含**propchange-email.pl**腳本(在Subversion源代碼樹中的`tools/hook-scripts/`目錄中),可以用來發送修訂版本屬性修改細節的email(并且或只是追加到一個日志文件)。這個email包含修訂版本和發生變化的屬性名,作出修改的用戶和新屬性值。
### 警告
不要嘗試用鉤子腳本修改事務。一個常見的例子就是在提交時自動設置`svn:eol-style`或`svn:mime-type`這類屬性。這看起來是個好主意,但它會引起問題。主要的問題是客戶并不知道由鉤子腳本進行的修改,同時沒有辦法通告客戶它的數據是過時的,這種矛盾會導致出人意料和不能預測的行為。
作為嘗試修改事務的替代,我們通過檢查`pre-commit`鉤子的事務,在不滿足要求時拒絕提交。
Subversion會試圖以當前訪問版本庫的用戶身份執行鉤子。通常,對版本庫的訪問總是通過Apache HTTP服務器和mod_dav_svn進行,因此,執行鉤子的用戶就是運行Apache的用戶。鉤子本身需要具有操作系統級的訪問許可,用戶可以運行它。另外,其它被鉤子直接或間接使用的文件或程序(包括Subversion版本庫本身)也要被同一個用戶訪問。換句話說,要注意潛在的訪問控制問題,它可能會讓你的鉤子無法按照你的目的順利執行。
### Berkeley DB配置
Berkeley DB環境是對一個或多個數據庫、日志文件、區域文件和配置文件的封裝。Berkeley DB環境對許多參數有自己的缺省值,例如任何時間里可用的鎖定數目、日志文件的最大值等。Subversion文件系統會使用Berkeley DB的默認值。 不過,有時候你的特定版本庫與它獨特的數據集合和訪問類型,可能需要不同的配置選項。
Sleepycat(Berkeley DB的制造廠商)的人們清楚不同的數據庫有不同的需求,所以他們提供了在運行中覆蓋Berkeley DB環境配置參數的機制。Berkeley在每一個環境目錄中檢查是否存在一個名叫`DB_CONFIG`的文件,然后解析其中的參數成為Berkeley環境所用的選項。
你的版本庫的Berkeley配置文件位于`db`目錄的`repos/db/DB_CONFIG`, Subversion在創建版本庫時自己創建了這個文件。這個文件初始時包含了一些默認選項,也包含了Berkeley DB在線文檔,使你能夠了解這些選項是做什么的。當然,你也可以為你的`DB_CONFIG` 文件添加任何Berkeley DB支持的選項。需要注意到,雖然Subversion不會嘗試讀取并解析這個文件,或使用其中的設置,你一定要避免會導致Berkeley DB按照Subversion代碼不習慣的方式工作的修改。另外,`DB_CONFIG`的修改在復原數據庫環境(用**svnadmin recover**)之前不會產生任何效果。
- 第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
- 術語表