### 使用API
使用Subversion庫API開發應用看起來相當的直接,所有的公共頭文件放在源文件的`subversion/include`目錄,從源代碼編譯和安裝Subversion本身,需要這些頭文件拷貝到系統位置。這些頭文件包括了所有用戶可以訪問的功能和類型。
你首先應該注意Subversion的數據類型和方法是命名空間保護的,每一個公共Subversion對象名以`svn_`開頭,然后緊跟一個這個對象定義(如`wc`、`client`和`fs`其他)所在的庫的簡短編碼,然后是一個下劃線(`_`)和后面的對象名稱。半公開的方法(庫使用,但是但庫之外代碼不可以使用并且只可以在庫自己的目錄看到)與這個命名模式不同,并不是庫代碼之后緊跟一個下劃線,他們是用兩個下劃線(`__`)。給定源文件的私有方法沒有特殊前綴,使用`static`聲明。當然,一個編譯器不會關心命名習慣,只是用來區分給定方法或數據類型。
### Apache可移植運行庫
伴隨Subversion自己的數據類型,你會看到許多`apr_`開頭的數據類型引用―來自Apache可移植運行庫(APR)的對象。APR是Apache可移植運行庫,源自為了服務器代碼的多平臺性,嘗試將不同的操作系統特定字節與操作系統無關代碼隔離。結果就提供了一個基礎API的庫,只有一些適度區別―或者是廣泛的―來自各個操作系統。Apache HTTP服務器很明顯是APR庫的第一個用戶,Subversion開發者立刻發現了使用APR庫的價值。意味著Subversion沒有操作系統特定的代碼,也意味著Subversion客戶端可以在Server存在的平臺編譯和運行。當前這個列表包括,各種類型的Unix、Win32、OS/2和Mac OS X。
除了提供了跨平臺一致的系統調用, APR給Subversion對多種數據類型有快速的訪問,如動態數組和哈希表。Subversion在代碼中廣泛使用這些類型,但是或許大多數普遍深入的APR數據類型可以在所有的Subversion的API原型中發現,是`apr_pool_t`―APR內存池,Subversion使用內部緩沖池用來進行內存分配(除非外部庫在API傳遞參數時需要一個不同的內存管理模式), 而且一個人如果針對Subversion的API編碼不需要做同樣的事情,他們可以在需要時給API提供緩沖池,這意味著Subversion的API使用者也必須鏈接到APR,必須調用`apr_initialize()`來初始化APR字系統,然后必須得到一個緩沖池用來進行Subversion的API調用。詳情見[“使用內存池編程”一節]。
### URL和路徑需求
因為分布式版本控制操作是Subversion存在的重點,有意義來關注一下國際化(i18n)支持。畢竟,當“分布式”或許意味著“橫跨辦公室”,它也意味著“橫跨全球”。為了更容易一點,Subversion的所有公共接口只接受路徑參數,這些參數是傳統的,使用UTF-8編碼。這意味著,舉個例子,任何新的使用libsvn_client接口客戶端庫,在把這些參數傳遞給Subversion庫前,需要首先將路徑從本地代碼轉化為UTF-8代碼,然后將Subversion傳遞回來的路徑轉換為本地代碼,很幸運,Subversion提供了一組任何程序可以使用的轉化方法(見`subversion/include/svn_utf.h`)。
同樣,Subversion的API需要所有的URL參數是正確的URI編碼,所以,我們不會傳遞`file:///home/username/My File.txt`作為`My File.txt`的URL,而會傳遞`file:///home/username/My%20File.txt`。再次,Subversion提供了一些你可以使用的助手方法―`svn_path_uri_encode`和`svn_path_uri_decode`,分別用來URI的編碼和解碼。
### 使用C和C++以外的語言
除C語言以外,如果你對使用其他語言結合Subversion庫感興趣―如Python腳本或是Java應用―Subversion通過簡單包裹生成器(SWIG)提供了最初的支持。Subversion的SWIG綁定位于`subversion/bindings/swig`,并且慢慢的走向成熟進入可用狀態。這個綁定允許你直接調用Subversion的API方法,使用包裹器會把腳本數據類型轉化為Subversion需要的C語言庫類型。
通過語言綁定訪問Subversion的API有一個明顯的好處―簡單性。通常來講,Python和Perl之類的語言比C和C++更加的靈活和簡單,這些語言的高級數據類型和上下文驅動類型更加易于處理用戶提供的信息,就像你知道的,人們精于把程序搞壞,腳本語言可以更優雅的處理這些錯誤信息,當然,靈活性經常帶來性能的損失,這就是為什么使用緊密優化的,C基礎的接口和庫組件,然后與一種高效的、靈活的綁定語言,是這樣的吸引人。
讓我們看看Subversion的Python SWIG綁定的實例,這個例子和前面的例子作同樣的事,注意比較方法的長度和復雜性!
**例8.2.使用Python處理版本庫層**
~~~
from svn import fs
import os.path
def crawl_filesystem_dir (root, directory, pool):
"""Recursively crawl DIRECTORY under ROOT in the filesystem, and return
a list of all the paths at or below DIRECTORY. Use POOL for all
allocations."""
# Get the directory entries for DIRECTORY.
entries = fs.dir_entries(root, directory, pool)
# Initialize our returned list with the directory path itself.
paths = [directory]
# Loop over the entries
names = entries.keys()
for name in names:
# Calculate the entry's full path.
full_path = os.path.join(basepath, name)
# If the entry is a directory, recurse. The recursion will return
# a list with the entry and all its children, which we will add to
# our running list of paths.
if fs.is_dir(fsroot, full_path, pool):
subpaths = crawl_filesystem_dir(root, full_path, pool)
paths.extend(subpaths)
# Else, it is a file, so add the entry's full path to the FILES list.
else:
paths.append(full_path)
return paths
~~~
前面C語言的實現確實有一點長,另外C語言的例行公事就是必須關注內存使用,并且需要使用自定義的數據類型來表示條目的哈希值和路徑列表。Python有哈希(叫做“dictionaries”)并且列表示內置數據類型,并提供了許多操作這些類型的好方法。而且因為Python使用引用計數來進行垃圾收集,這種語言的用戶不需要麻煩自己去分配和回收內存。
在本章的前面小節,我們提到`libsvn_client`接口,并且解釋了它存在的唯一目的是為了簡化編寫Subversion客戶端的過程,下面是一個如何同SWIG綁定訪問庫的簡短例子,簡單的幾句Python代碼,我們就可以檢出一個完全功能的Subversion工作拷貝!
**例8.3.一段檢出工作拷貝的簡單腳本**
~~~
#!/usr/bin/env python
import sys
from svn import util, _util, _client
def usage():
print "Usage: " + sys.argv[0] + " URL PATH\n"
sys.exit(0)
def run(url, path):
# Initialize APR and get a POOL.
_util.apr_initialize()
pool = util.svn_pool_create(None)
# Checkout the HEAD of URL into PATH (silently)
_client.svn_client_checkout(None, None, url, path, -1, 1, None, pool)
# Cleanup our POOL, and shut down APR.
util.svn_pool_destroy(pool)
_util.apr_terminate()
if __name__ == '__main__':
if len(sys.argv) != 3:
usage()
run(sys.argv[1], sys.argv[2])
~~~
非常不幸,Subversion的語言綁定缺乏對核心Subversion模塊的關注,但是,使用Python、Perl和Java創建有功能的邦定取得了顯著的成就。一旦你的SWIG接口文件正確的配置,對于SWIG支持的語言(我們當前包括的版本有C#、Guile、Java、MzScheme、OCaml、Perl、PHP、Python、Ruby和Tcl)的特定語言綁定的包裹器的生成理論上是非常瑣碎的。但是,對復雜API還是需要一些額外的的補充,SWIG需要幫助歸納。對于SWIG的更多信息,見這個項目的網站`http://www.swig.org/`。
Subversion使用盡可能多ANSI系統調用和數據類型。
Neon和Berkeley DB就是這種庫的例子。
- 第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
- 術語表