リポジトリの作成と設定

Subversionリポジトリの作成は非常に簡単な作業です。 Subversion付属のsvnadmin ユーティリティー にそれをやるサブコマンドがあります。新しいリポジトリを作るには 単に:

$ svnadmin create /path/to/repos

これで/path/to/reposディレクトリに 新しいリポジトリが作成されます。この新しいリポジトリはリビジョン0 で誕生しますが、これは最上位のルート(/) ファイル システムディレクトリに中身が空の状態で存在しているだけです。 初期状態でリビジョン0はリビジョン属性を一つ持っていて、 svn:dateは、リポジトリが作られた時刻が設定 されています。

Subversion 1.2 では、リポジトリはデフォルトで FSFS のバッ クエンドになります。(リポジトリの保存形式項 を見てください)。バックエンドは--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 DB は利用する ファイルシステムが POSIX のロックの方式に厳密に従っていること、そしてさらに 重要なことは、ファイルをプロセスメモリに直接マップできること、を要求します。 ネットワークファイルシステムでこの性質を持っているものはほとんどありません。 ネットワーク上で共有された場所の上で Berkeley DB を利用した結果については予測できません— すぐに正体不明のエラーが起きるかも知れませんし、自分のデータベースがわずかに 壊れてしまったことに気づくのに何ヶ月もかかるかも知れません。

もしリポジトリに対して複数のコンピュータがアクセスする必要がある なら、ネットワーク共有上に Berkeley DB リポジトリではなく、FSFS リポジ トリを作ってください。あるいはもっと良い方法として、実際の(Apache か svnserveのような)サーバプロセ スを設定し、サーバがアクセスできるようなローカルファイルシステム上にリ ポジトリを格納し、リポジトリがネットワークからも利用できるようにしてく ださい。章 6. サーバの設定でこのやり方の詳細を説明しています。

svnadmin の引数であるパスは単なるファイルシステム パスであってsvn クライアントプログラムがリポジトリ を参照するときのようなURLではないことに注意してください。 svnadminsvnlook も、 サーバ側のユーティリティーだと考えてください— この二つはリポジトリを調べたり状態を変更するため、リポジトリがある マシン上で利用され、ネットワーク越しに実行することはできません。 Subversion初心者によくある間違いは、二つのプログラムに、URLを 渡してしまうことです。(あるいは、「local」な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 環境 (DB テーブルとその他必要な全体)か、 リビジョンファイルを含む FSFS 環境になります。

format

一つの整数値が書いてあるファイルで、この整数はリポジトリレイアウトの バージョン番号になります。

hooks

フックスクリプトテンプレート全体が格納されたディレクトリです (また、インストールされたフックスクリプト自身も)。

locks

Subversionリポジトリのロックされたデータのためのディレクトリで リポジトリにアクセスしている人を記録するのに使われます。

README.txt

Subversionリポジトリを見る人のための情報が書かれている だけのファイルです。

一般的に、「手で」リポジトリをいじるべきではありません。 svnadmin ツールはリポジトリに対するどのような 変更にも十分対応できますし、サードパーティーのツール(たとえば Berkeley DBツールスイート)でリポジトリの関連した部分を調整する ことができます。いくつかの例外もあるので、それについては後で触れます。

フックスクリプト

hook は、新しいリビジョンの生成やバージョン化されて いない属性の修正といったリポジトリに対するイベントをきっかけに実行される プログラムです。フックのそれぞれは、どんなイベントが起こったか、 何を対象にして操作をしたのか、そのイベントを起こした人のユーザ名 などの情報を扱うことができます。フックの出力や戻り値によって フックプログラムは処理を続けたり終了したり、いくつかの方法で中断したりします。

hooks サブディレクトリには、デフォルトでは さまざまなリポジトリフックのテンプレートがあります。

$ ls repos/hooks/
post-commit.tmpl          post-unlock.tmpl          pre-revprop-change.tmpl
post-lock.tmpl            pre-commit.tmpl           pre-unlock.tmpl
post-revprop-change.tmpl  pre-lock.tmpl             start-commit.tmpl

Subversionが実装しているフックごとに一つのテンプレートがあり、 テンプレートスクリプトの内容を見ればどんなトリガーを実行し、 どんなデータがそのスクリプトに渡されるかがわかります。 またこれらたくさんのテンプレートはスクリプトを書こうとする人の例 になっていて、他のSubversion付属のプログラムと協調して、よく出くわす 作業を実行します。 動作するフックをインストールするには、何かの実行ファイルかスクリプト をrepos/hooks ディレクトリに置くだけで良く、 そのフックの名前で実行されます。(start-commit とか post-commitとかいう感じです。)

Unixでは、これは正確にフックの名前を持つスクリプトやプログラムを 置いてやる必要があるという意味です(シェルスクリプトでもいいし、 Python, コンパイルされた Cのプログラム、などなどです。) もちろんテンプレートファイルはそういう情報を与えるためだけに あるわけではありません—Unixで一番簡単にフックをインストール するにはテンプレートファイルを.tmpl の拡張子を とった新しいファイルにコピーして、内容をカスタマイズし、スクリプトに 実行権限を与えるだけです。Windowsでは、ファイルが実行できるかどうか は拡張子によって決まるので、ベース名がフックの名前で、拡張子がWindows で実行形式として認識される拡張子のどれかにしてやればOKです。 たとえば、プログラムなら.exe.com ですし、バッチファイルなら.bat です。

ティップ

セキュリティー上の理由で、Subversion リポジトリはフックスクリプト を空の環境で実行します— つまり$PATH%PATH%を含め、環境変数は全く設定されない 状態で実行します。このため多くの管理者は手でフックスクリプトを実行 するとうまくいくのに、Subversion によって実行されたときにはうまくいかな いことに困惑します。環境変数を明示的に設定するか、実行するプログラム を絶対パスで参照していることを確認してください。

Subversionリポジトリには9種類のフックが実装されています:

start-commit

これは、コミットトランザクションが作られる前に実行されます。 典型的にはユーザがコミット権限があるかどうかを決定するのに 使われます。リポジトリはこのプログラムに二つの引数を渡します: リポジトリへのパスと、コミットしようとしているユーザ名です。 もしプログラムがゼロ以外の値を返した場合、コミットは ランザクションが作られる前に中止します。フックが標準エラー出力にデータ を書き込むと、それは適切なデータ形式でクライアントに戻されます。

pre-commit

これは、トランザクションの完結後、実際のコミットの前に実行 されます。典型的には、コミットの内容や場所(たとえば あなたのサイトでは、すべてのコミットはバグトラッカーの管理番号 を含むようなブランチに対してしなくてはならないとか、 ログメッセージが空であってはいけないというようなポリシーが あるかも知れません) によってコミットを許可しないようにするために使われます。 リポジトリはこのプログラムに二つの引数を渡します: リポジトリのパスと、コミットされるはずのトランザクションの名前 です。もしこのプログラムがゼロ以外の値を返した場合、 コミットは中断され、トランザクションは削除されます。 フックが標準エラー出力にデータ を書き込むと、それは適切なデータ形式でクライアントに戻されます。

Subversionの配布パッケージは、アクセス制御を細かく実装するために pre-commitから呼び出すことのできるいくつかの アクセス制御スクリプトを含んでいます(Subversionソースツリーの tools/hook-scripts ディレクトリにあります)。 他の選択子はApache の httpd モジュールであるmod_authz_svn を使うもので、個別のディレクトリに対する読みこみ書き込みのアクセス制御 をすることができます(ディレクトリごとのアクセス制御項を見てください)。 Subversion の今後のバージョンでは、ファイルシステムに直接アクセス制御リス ト(ACL)を実装する計画があります。

post-commit

これはトランザクションがコミットされ、新しいリビジョンが 作られた後に実行されます。ほとんどの人はこのフックを リポジトリのコミットやバックアップに関する連絡メールを 送るのに使います。リポジトリはこのプログラムに二つの引数を 渡します:リポジトリのパスと、今回作られた新しいリビジョン番号 です。このプログラムの終了コードは無視されます。

Subversion配布パッケージはmailer.pycommit-email.pl スクリプトを含んでいます。(Subversionソースツリーの tools/hook-scripts/ ディレクトリにあります) それは、今回のコミットに付けられた説明をメールするために使う ことができます。このメールの内容は変更されたパスの一覧、コミットに 付けたログメッセージ、コミットした人、コミットの時刻、そして、 コミットの変更部分のGNU のdiffスタイルでの表示です。

Subversionが提供するほかの役に立つツールはhot-backup.py スクリプトです。(Subversionソースツリーのtools/backup/ ディレクトリにあります)。このスクリプトはSubversionリポジトリの オンラインバックアップをとるので、(今後はBerkeleyDBデータベース のバックエンドとしてサポートする予定です)リポジトリのアーカイブ化 や緊急リカバリのためのコミットごとのスナップショットを作るのに 使うことができます。

pre-revprop-change

Subversionのリビジョン属性はバージョン化されていないので、そのような 属性に対する修正は(たとえば、コミットメッセージ属性である svn:log )以前の属性値を永久に上書きしてしまいます。 データはここで失われてしまうので、Subversionはこのフック(そして この相補的な部分である post-revprop-change) を使って、必要に応じてリポジトリ管理者がこのような変更記録を残すことが 出来ます。バージョン化されていない属性データを失うことに対するあらかじめ の警告の意味で、Subversion クライアントはこのフックが自分のリポジトリに 実装されているのではない限りリビジョン属性をリモートに変更することは 決してありません。

このフックはリポジトリにそのような変更が発生する直前に実行されます。 リポジトリはこのフックに四つの引数を与えます: リポジトリのパス、修正される属性があるリビジョン、 変更しようとしている、認証の済んだユーザ名、そして属性の名前自身です。

post-revprop-change

以前に指摘したように、このフックはpre-revprop-change フックのもう片割れです。実際、神経質な人のことを考えて、このスクリプト はpre-revprop-change フックが存在しなければ 実行されません。両方のフックが存在する場合、 post-revprop-change フックはリビジョン属性が変更 された直後に実行されます。典型的には、変更された属性の新しい値を メールするのに使います。リポジトリは四つの引数をこのフックに渡します: リポジトリへのパス、属性があるリビジョン番号、変更しようと している認証済みのユーザ名称、そして属性の名前自身です。

Subversion配布パッケージは propchange-email.pl スクリプトを含んでいます。(これは、tools/hook-scripts/ ディレクトリにあります)これは、リビジョン属性の変更についての詳細を メールするために使われます。Emailはリビジョンと変更属性の名前、 変更した人、そして新しい属性値です。

pre-lock

このフックは誰かがファイルをロックしようとしたときには常に実行されます。 これはロックを防ぐのにも利用するこどかできますし、誰が特定のパスに対して ロックできるかという複雑なポリシーを正確に設定するのにも使えます。 フックが既にロックがかかっていることに気づいた場合にはユーザはそのロック が外れるのを 「待つ」 かどうかを決めることもできます。リポジトリはフックに 三つの引数を渡します: リポジトリへのパス、ロックされているパス、そして ロックしようとしているユーザです。プログラムが 0 ではない値で終了すると ロック処理は異常終了し、標準エラー出力へのメッセージはすべてクライアント 側に転送されます。

post-lock

このロックはパスがロックされた後に実行されます。ロックされたパスはフックの 標準入力に渡されるほか、フックはまた二つの引数も受け取ります: リポジトリ へのパスと、ロックを実行したユーザです。その後フックは email 通知を送ったり 好きな方法で出来事を記録したりすることが自由にできます。ロックはすでに 実行されてしまっているのでフックの出力は無視されます。

pre-unlock

このフックは誰かがファイルのロックを取り除こうとした時には常に 実行されます。これを使ってどのユーザがどの特定のパスに対して ロック解除できるかを決めるポリシーを作るために利用できます。 ロック解除に関するポシリーを決めることは非常に重要です。 ユーザ A がファイルをロックした場合、B はそのロックを解除できる でしょうか? ロックが一週間以上も前のものだった場合は? これらの ことはフックによって決定され、強制することができます。リポジトリ は三つの引数をフックに送ります: リポジトリのパス、ロック解除される パス、ロックを解除しようとしているユーザ。プログラムが 0 以外の 終了値を返した場合、ロック解除の処理は異常終了し標準エラーへの 出力はすべてクライアント側に転送されます。

post-unlock

このフックはパスがロック解除された後で実行されます。ロックが解除 されたパスはフックの標準入力に渡され、その他にも二つの引数がフック に渡されます: リポジトリのパスと、ロックを解除したユーザです。 その後フックは email 通知を送ったり、好きな方法で出来事を記録する ことができます。ロックの解除は既に起こってしまっているのでフックの 出力は無視されます。

警告

フックスクリプトによってトランザクションを修正しようとしないで ください。このような例としてよくあるのは、コミットの途中に svn:eol-stylesvn:mime-type のような属性を自動的に設定してしまうことです。いっけん良いアイディア に見えますが、問題を起こします。一番の問題はクライアントはフックスクリ プトでされた変更について知ることができないので、クライアントに対して 最新ではなくなったことを伝える方法がないことです。この矛盾した状況 が予測できないような動作の原因になることがあります。

トランザクションで修正するかわりにpre-commit フック中のトランザクションで チェックをし、 正しい要件を満たさない場合にはコミットを拒否するのがずっと良い 方法です。

SubversionはSubversionリポジトリにアクセスしているプロセス の所有者としてフックを実行しようとします。ほとんどの場合 リポジトリはApache HTTPサーバとmod_dav_svn越しにアクセスされる ので、このユーザはApacheを実行しているユーザと同じになります。 フックは、実行しようとするユーザに対するOSレベルでの実行権限 が必要です。また、これはフックが直接的に、間接的にアクセスする ファイルやディレクトリ(これにはSubversionのリポジトリ自身も 含みますが)もそうでなくてはならないことを意味します。 言い換えるとフックを実行する際に、このようなファイル権限に 関係した問題に注意してください。

Berkeley DB の設定

Bkerlekey DB 環境は一つあるいはそれ以上のデータベース、ログファイル、 領域ファイル、設定ファイルを一つにまとめたものです。 Berkeley DB 環境には、一度にいくつのロックが許されるか、 とか、ジャーナルログファイルの一つの大きさについて、固有のデフォルト 値があります。Subversionのファイルシステムコードはこれに追加して Berkeley DB 設定値のデフォルト値を選んであります。しかし、 ときどき特定のリポジトリが特徴的なデータやアクセスパターンを 持っているために別のオプション設定値を持つのが望ましいことがあります。

Sleepycat 系のプログラム(Berkeley DBの手続き)は異なるデータベース が異なる要求を持つことを理解していて、Berkeley DB環境のいろいろな 設定値を実行時に上書きするような仕組みがあります。Berkeley は それぞれの環境ディレクトリ中のDB_CONFIG という名前のファイルの存在をチェックして、特別の Berkeley 環境 を使う場合には、その中のオプションを調べます。

あなたのリポジトリ用のBerkeley設定ファイルは repos/db/DB_CONFIGの中の、 db環境ディレクトリにあります。 Subversion自身はこのファイルをリポジトリの残りの部分を作るときに 作ります。ファイルは初期状態でいくつかのデフォルト値と、Berkeley DB のオンラインドキュメントへの場所があるので、どのオプションが 何をするかについて読んでおくことができます。もちろんどのような Berkeley DBオプションもDB_CONFIG に追加 することができます。Subversionはこのファイルの内容を読んだり 解釈したりすることはありませんし、その中にオプション値を設定 したりすることもありませんが、Subversionの残りのコードに 予測できないような影響を与える設定変更は避けてください。 同様にDB_CONFIGに対する変更はデータベース 環境を復旧するまで効果を持ちません(svnadmin recover )。