Subversion has a modular design: it's implemented as a collection of libraries written in C. Each library has a well-defined purpose and Application Programming Interface (API), and that interface is available not only for Subversion itself to use, but for any software that wishes to embed or otherwise programmatically control Subversion. Additionally, Subversion's API is available not only to other C programs, but also to programs written in higher-level languages such as Python, Perl, Java, or Ruby.
本章是为那些希望编写代码或其他语言绑定与Subversion交互的人准备的。如果
Each of Subversion's core libraries can be said to exist in one of three main layers—the Repository Layer, the Repository Access (RA) Layer, or the Client Layer (see 图 1 “Subversion 的架构”). We will examine these layers shortly, but first, let's briefly summarize Subversion's various libraries. For the sake of consistency, we will refer to the libraries by their extensionless Unix library names (libsvn_fs, libsvn_wc, mod_dav_svn, etc.).
客户端程序的主要接口
目录树和文本区别程序
上下文区别和合并例程
Subversion文件系统库和模块加载器
Berkeley DB文件系统后端
本地文件系统(FSFS)后端
版本库访问通用组件和模块装载器
WebDAV版本库访问模块
本地版本库访问模块
另一个(实验性的) WebDAV 版本库访问模块
一个自定义版本库访问模块
版本库接口
各色各样的有用的子程序
工作拷贝管理库
使用WebDAV访问Subversion版本库的Apache授权模块
影射WebDAV操作为Subversion操作的Apache模块
The fact that the word “miscellaneous” only appears once in the previous list is a good sign. The Subversion development team is serious about making sure that functionality lives in the right layer and libraries. Perhaps the greatest advantage of the modular design is its lack of complexity from a developer's point of view. As a developer, you can quickly formulate that kind of “big picture” that allows you to pinpoint the location of certain pieces of functionality with relative ease.
模块化的另一个好处是我们有能力去构造一个全新的,能够完全实现相同API功能的库,以替换整个给定的模块,而又不会影响基础代码。在某种意义上,Subversion已经这样做了。libsvn_ra_dav、libsvn_ra_local、libsvn_ra_serf和libsvn_ra_svn all都实现了相同的接口,均与版本库层进行通讯—libsvn_ra_loca与版本库直接连接其他几个则通过网络。 libsvn_fs_base和libsvn_fs_fs库是另外一对以不同方式实现相同功能的库—都是可以与libsvn_fs库连接。
The client itself also highlights the benefits of modularity in the Subversion design. Subversion's libsvn_client library is a one-stop shop for most of the functionality necessary for designing a working Subversion client (see “客户端层”一节). So while the Subversion distribution provides only the svn command-line client program, there are several third-party programs which provide various forms of graphical client UI. These GUIs use the same APIs that the stock command-line client does. This type of modularity has played a large role in the proliferation of available Subversion clients and IDE integrations and, by extension, to the tremendous adoption rate of Subversion itself.
当提到Subversion版本库层时,我们通常会讨论两个基本概念—版本化文件系统实现(通过libsvn_fs访问,libsvn_fs_base和libsvn_fs_fs支持),和包装在外的(以libsvn_repos实现)版本库逻辑。这些库提供了版本控制数据的存储和报告机制,这些层通过版本库访问层连接客户端层,从Subversion用户的角度,这些事情在整个过程的另一端。
The Subversion Filesystem is not a kernel-level filesystem that one would install in an operating system (like the Linux ext2 or NTFS), but a virtual filesystem. Rather than storing “files” and “directories” as real files and directories (as in, the kind you can navigate through using your favorite shell program), it uses one of two available abstract storage backends—either a Berkeley DB database environment, or a flat-file representation. (To learn more about the two repository back-ends, see “选择数据存储格式”一节.) There has even been considerable interest by the development community in giving future releases of Subversion the ability to use other back-end database systems, perhaps through a mechanism such as Open Database Connectivity (ODBC). In fact, Google did something similar to this before launching the Google Code Project Hosting service: they announced in mid-2006 that members of its Open Source team had written a new proprietary Subversion filesystem plugin which used their ultra-scalable Bigtable database for its storage.
libsvn_fs支持的文件系统API包含了所有其他文件系统的功能:你可以创建和删除文件和目录、拷贝和移动、修改文件内容等等。它也包含了一些不太常用的特性,如对任意文件和目录添加、修改和删除元数据(“properties”)的能力。此外,Subversion文件系统是一个版本化的文件系统,意味着你修改你的目录树时,Subversion会记住修改以前的样子。也可以回到所有初始化版本库之后(且仅仅之后)的版本。
所有你对目录树的修改包含在Subversion事务的上下文中,下面描述了修改文件系统的例程:
开始 Subversion 的提交事务。
作出修改(添加、删除、属性修改等等。)。
提交事务。
一旦你提交了你的事务,你的文件系统修改就会永久的作为历史保存起来,每个这样的周期会产生一个新的树,所有的修订版本都是永远可以访问的一个不变的快照。
Most of the functionality provided by the filesystem
interface deals with actions that occur on individual
filesystem paths. That is, from outside of the filesystem, the
primary mechanism for describing and accessing the individual
revisions of files and directories comes through the use of
path strings like /foo/bar, just as if
you were addressing files and directories through your
favorite shell program. You add new files and directories by
passing their paths-to-be to the right API functions. You
query for information about them by the same mechanism.
然而,不像大多数文件系统,一个单独的路径不足以在Subversion定位一个文件或目录,可以把目录树看作一个二维的系统,一个节点的兄弟代表了一种从左到右的动作,并且递减到子目录是一个向下的动作,图 8.1 “二维的文件和目录”展示了一个典型的树的形式。
The difference here is that the Subversion filesystem has a
nifty third dimension that most filesystems do not
have—Time!
[50]
In the filesystem interface, nearly every function that has a
path argument also expects a
root argument. This svn_fs_root_t argument describes
either a revision or a Subversion transaction (which is simply
a revision-in-the-making), and provides that third-dimensional
context needed to understand the difference between
/foo/bar in revision 32, and the same
path as it exists in revision 98. 图 8.2 “版本时间—第三维!” shows revision
history as an added dimension to the Subversion filesystem
universe.
像之前我们提到的,libsvn_fs的API感觉像是其它文件系统,只是有一个美妙的版本化能力。它设计为为所有对版本化的文件系统有兴趣的程序使用,不是巧合,Subversion本身也对这个功能很有兴趣。但是虽然文件系统API一定必须对基本的文件和目录版本化提供足够的支持,Subversion需要的更多—这是libsvn_repos到来的地方。
Subversion版本库库(libsvn_repos)建立在(逻辑上讲)libsvn_fs的API之上,不仅仅提供了版本化文件系统的功能,它没有包裹所有的文件系统功能—只有文件系统常规周期中的主要事件使用版本库接口包裹,如包括Subversion事务的创建和提交,修订版本属性的修改。这些特别的事件使用版本库库包裹是因为它们有一些关联的钩子。版本库钩子系统并没有与与版本化文件系统的紧密关联,所以它们存在于版本库的包裹库。
钩子机制需求是从文件系统代码的其它部分中抽象出单独的版本库库的一个原因,libsvn_repos的API提供了许多其他有用的工具,它们可以做到:
在Subversion版本库和版本库包括的文件系统的上创建、打开、销毁和执行恢复步骤。
描述两个文件系统树的区别。
关于所有(或者部分)修订版本中的文件系统中的一组文件的提交日志信息的查询
产生可读的文件系统“导出”,一个文件系统修订版本的完整展现。
解析导出格式,加载导出的版本到一个不同的Subversion版本库。
伴随着Subversion的发展,版本库库会随着文件系统提供更多的功能和配置选项而不断成长。
If the Subversion Repository Layer is at “the other end of the line”, the Repository Access (RA) Layer is the line itself. Charged with marshaling data between the client libraries and the repository, this layer includes the libsvn_ra module loader library, the RA modules themselves (which currently includes libsvn_ra_dav, libsvn_ra_local, libsvn_ra_serf, and libsvn_ra_svn), and any additional libraries needed by one or more of those RA modules (such as the mod_dav_svn Apache module or libsvn_ra_svn's server, svnserve).
Since Subversion uses URLs to identify its repository
resources, the protocol portion of the URL scheme (usually
file://, http://,
https://, svn://, or
svn+ssh://) is used to determine which RA
module will handle the communications. Each module registers
a list of the protocols it knows how to “speak”
so that the RA loader can, at runtime, determine which module
to use for the task at hand. You can determine which RA
modules are available to the Subversion command-line client,
and what protocols they claim to support, by running
svn --version:
$ svn --version svn, version 1.4.3 (r23084) compiled Jan 18 2007, 07:47:40 Copyright (C) 2000-2006 CollabNet. Subversion is open source software, see http://subversion.tigris.org/ This product includes software developed by CollabNet (http://www.Collab.Net/). The following repository access (RA) modules are available: * ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol. - handles 'http' scheme - handles 'https' scheme * ra_svn : Module for accessing a repository using the svn network protocol. - handles 'svn' scheme * ra_local : Module for accessing a repository on local disk. - handles 'file' scheme $
The public API exported by the RA Layer contains functionality necessary for sending and receiving versioned data to and from the repository. And each of the available RA plugins is able to perform that task using a specific protocol—libsvn_ra_dav speaks HTTP/WebDAV (optionally using SSL encryption) with an Apache HTTP Server that is running the mod_dav_svn Subversion server module; libsvn_ra_svn speaks a custom network protocol with the svnserve program; and so on.
对那些一直希望使用另一个协议来访问Subversion版本库的人,正好是为什么版本库访问层是模块化的!开发者可以简单的编写一个新的库来在一侧实现RA接口并且与另一侧的版本库通讯。你的新库可以使用存在的网络协议,或者发明你自己的。你可以使用进程间的通讯调用,或者—让我们发狂,我们会吗?—你甚至可以实现一个电子邮件为基础的协议,Subversion提供了API,你提供创造性。
在客户端这一面,Subversion工作拷贝是所有动作发生的地方。大多数客户端库实现的功能是为了管理工作拷贝的目的实现的—满是文件子目录的目录是一个或多个版本库位置的可编辑的本地“影射”—从版本库访问层来回传递修改。
Subversion's working copy library, libsvn_wc, is directly
responsible for managing the data in the working copies. To
accomplish this, the library stores administrative information
about each working copy directory within a special
subdirectory. This subdirectory, named
.svn, is present in each working copy
directory and contains various other files and directories
which record state and provide a private workspace for
administrative action. For those familiar with CVS, this
.svn subdirectory is similar in purpose
to the CVS administrative directories
found in CVS working copies. For more information about the
.svn administrative area, see “进入工作拷贝的管理区”一节in this chapter.
The Subversion client library, libsvn_client, has the
broadest responsibility; its job is to mingle the
functionality of the working copy library with that of the
Repository Access Layer, and then to provide the highest-level
API to any application that wishes to perform general revision
control actions. For example, the function
svn_client_checkout() takes a URL as an
argument. It passes this URL to the RA layer and opens an
authenticated session with a particular repository. It then
asks the repository for a certain tree, and sends this tree
into the working copy library, which then writes a full
working copy to disk (.svn directories
and all).
The client library is designed to be used by any
application. While the Subversion source code includes a
standard command-line client, it should be very easy to write
any number of GUI clients on top of the client library. New
GUIs (or any new client, really) for Subversion need not be
clunky wrappers around the included command-line
client—they have full access via the libsvn_client API
to same functionality, data, and callback mechanisms that the
command-line client uses. In fact, the Subversion source code
tree contains a small C program (which can be found at
tools/examples/minimal_client.c that
exemplifies how to wield the Subversion API to create a simple
client program