嵌入 Subversion

目录

分层的库设计
版本库层
版本库访问层
客户端层
进入工作拷贝的管理区
条目文件
原始拷贝和属性文件
使用 API
Apache 可移植运行库
URL 和路径需求
使用 C 和 C++ 以外的语言
代码样例

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.).

libsvn_client

客户端程序的主要接口

libsvn_delta

目录树和文本区别程序

libsvn_diff

上下文区别和合并例程

libsvn_fs

Subversion文件系统库和模块加载器

libsvn_fs_base

Berkeley DB文件系统后端

libsvn_fs_fs

本地文件系统(FSFS)后端

libsvn_ra

版本库访问通用组件和模块装载器

libsvn_ra_dav

WebDAV版本库访问模块

libsvn_ra_local

本地版本库访问模块

libsvn_ra_serf

另一个(实验性的) WebDAV 版本库访问模块

libsvn_ra_svn

一个自定义版本库访问模块

libsvn_repos

版本库接口

libsvn_subr

各色各样的有用的子程序

libsvn_wc

工作拷贝管理库

mod_authz_svn

使用WebDAV访问Subversion版本库的Apache授权模块

mod_dav_svn

影射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事务的上下文中,下面描述了修改文件系统的例程:

  1. 开始 Subversion 的提交事务。

  2. 作出修改(添加、删除、属性修改等等。)。

  3. 提交事务。

一旦你提交了你的事务,你的文件系统修改就会永久的作为历史保存起来,每个这样的周期会产生一个新的树,所有的修订版本都是永远可以访问的一个不变的快照。

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 “二维的文件和目录”展示了一个典型的树的形式。

图 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.

图 8.2. 版本时间—第三维!


像之前我们提到的,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



[50] 我们理解这一定会给科幻小说迷带来一个震撼,他们认为时间是第四维的,我们要为提出这样一个不同理论的断言而伤害了他们的作出道歉。