階層化されたライブラリ設計

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

ファイルシステムの共通関数と、モジュールローダー

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.

Another benefit of modularity is the ability to replace a given module with a whole new library that implements the same API without affecting the rest of the code base. In some sense, this happens within Subversion already. The libsvn_ra_dav, libsvn_ra_local, libsvn_ra_serf, and libsvn_ra_svn libraries each implement the same interface, all working as plugins to libsvn_ra. And all four communicate with the Repository Layer—libsvn_ra_local connects to the repository directly; the other three do so over a network. The libsvn_fs_base and libsvn_fs_fs libraries are another pair of libraries that implement the same functionality in different ways—both are plugins to the common libsvn_fs library.

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.

リポジトリ層

When referring to Subversion's Repository Layer, we're generally talking about two basic concepts—the versioned filesystem implementation (accessed via libsvn_fs, and supported by its libsvn_fs_base and libsvn_fs_fs plugins), and the repository logic that wraps it (as implemented in libsvn_repos). These libraries provide the storage and reporting mechanisms for the various revisions of your version-controlled data. This layer is connected to the Client Layer via the Repository Access Layer, and is, from the perspective of the Subversion user, the stuff at the 「other end of the line.

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.

The filesystem API exported by libsvn_fs contains the kinds of functionality you would expect from any other filesystem API—you can create and remove files and directories, copy and move them around, modify file contents, and so on. It also has features that are not quite as common, such as the ability to add, modify, and remove metadata (「properties」) on each file or directory. Furthermore, the Subversion Filesystem is a versioning filesystem, which means that as you make changes to your directory tree, Subversion remembers what your tree looked like before those changes. And before the previous changes. And the previous ones. And so on, all the way back through versioning time to (and just beyond) the moment you first started adding things to the filesystem.

All the modifications you make to your tree are done within the context of a Subversion commit transaction. The following is a simplified general routine for modifying your filesystem:

  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! [53] 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 が 提供するものです。

The Subversion repository library (libsvn_repos) sits (logically speaking) atop the libsvn_fs API, providing additional functionality beyond that of the underlying versioned filesystem logic. It does not completely wrap each and every filesystem function—only certain major steps in the general cycle of filesystem activity are wrapped by the repository interface. Some of these include the creation and commit of Subversion transactions, and the modification of revision properties. These particular events are wrapped by the repository layer because they have hooks associated with them. A repository hook system is not strictly related to implementing a versioning filesystem, so it lives in the repository wrapper library.

The hooks mechanism is but one of the reasons for the abstraction of a separate repository library from the rest of the filesystem code. The libsvn_repos API provides several other important utilities to Subversion. These include the abilities to:

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

And for those who wish to access a Subversion repository using still another protocol, that is precisely why the Repository Access Layer is modularized! Developers can simply write a new library that implements the RA interface on one side and communicates with the repository on the other. Your new library can use existing network protocols, or you can invent your own. You could use inter-process communication (IPC) calls, or—let's get crazy, shall we?—you could even implement an email-based protocol. Subversion supplies the APIs; you supply the creativity.

クライアント層

クライアント側から見ると、Subversionの作業コピーは すべての処理が起こる場所です。クライアント側ライブラリによって 実装される機能は、作業コピーの管理というただ一つの目的のために 存在します—ローカルな場所に何らかの形で提供される ファイルと他のサブディレクトリのあるディレクトリが、一つ以上の リポジトリ位置を「反映した」ものとし、リポジトリアクセス層との間の 変更を伝えたりします。

Subversionの作業コピーライブラリ、libsvn_wc は作業コピー中の データの管理に直接の責任を負います。これをやるために、このライブラリ は特別なサブディレクトリの中にそれぞれの作業コピーについての管理情報 を格納します。このサブディレクトリは.svn という 名前ですが、どの作業コピー中にも存在し、管理に関係した動作を するための状態を記録し、作業スペースを確保するためのさまざまな ファイルやディレクトリを含んでいます。CVSになじみのある人なら、 この.svn サブディレクトリは、その目的としては CVSの作業コピーにある管理ディレクトリCVS に よく似ていることがわかると思います。.svn 管理領域についての詳細は、この章の 作業コピー管理領域の内部項を参照してください

Subversionクライアントライブラリ libsvn_client は広範囲の役目を 負います。その仕事は、作業コピーライブラリの機能と、リポジトリアクセス層 の機能を結びつけることで、一般的なリビジョン制御を実行したいと思う すべてのアプリケーションに最上位のAPIを提供することです。たとえば svn_client_checkout() 関数は引数としてURLを とります。この関数は URLを RA層に渡し、特定のリポジトリに認証された セッションを開きます。それからそのリポジトリに特定のツリーを指定し、 このツリーを作業コピーライブラリに送りますが、今度はそのライブラリが 作業コピー全体をディスクに書き込みます(.svn ディレクトリを含むすべての情報)。

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



[53] We understand that this may come as a shock to sci-fi fans who have long been under the impression that Time was actually the fourth dimension, and we apologize for any emotional trauma induced by our assertion of a different theory.