SubversionはどのOS上で動作するの? ¶
最近のUNIXや、Win32、BeOS、OS/2、MacOS Xで動作する。
Subversionは ANSI C で書かれていて、APR(Apache Portable Rutime Library)をポータビリティ実現の為に使っている。 Subversionクライアントは、APRを稼動可能なOS上ならば何処ででも動作するだろうから、多くの環境で使うことが出来る。 Subversionサーバ(つまり、リポジトリ側)についても同様だけど、Win9xプラットフォーム(Win95/Win98/WinME)では、Berkeley DBリポジトリを使うことは出来ない。 これは、Win95上の Berkeley DB に、shared-memory セグメント問題が存在するためだ。(version 1.1から導入された)FSFSリポジトリにはこの制約は存在しない。 しかし、Win9xのファイルロックサポートの制限により、こちらもWin9x 上では、動作しない。
整理すると、Subversionクライアントは、APRが動作するプラットフォーム上でならばどこででも動作する。 Subversionサーバも、APRが動作する全てのプラットフォームで動作するが、Win95/Win98/WinMeではリポジトリを提供することは出来ない。
Subversionサーバを動作させるためには、どんなハードウェアが必要? ¶
サーバの要求は多くの要素が関係してくる。 例えば、ユーザ数や、コミットを初めとするサーバ関連操作の頻度、リポジトリのサイズ、独自に設定したリポジトリフックの負荷などだ。 もし、Apacheを使っているならば、Apache自体がメモリ使用量の最大要因となるだろう。より詳しい話は、メイリングリストの議論を参照してほしい。
同じサーバ上で動作している、他のアプリケーションを考慮に入れるのを忘れないこと。 例えば、リポジトリブラウザを使うのであれば、Subversion 自体とは関係なくリソースが必要になる。
一般的に行って、同等のCVSリポジトリと比べて、より少ないサーバメモリで済むことは期待して良いよ。
Subversion には「チェンジセット」って存在する? ¶
この質問は、ちょっと厄介だ。 というのは、皆「チェンジセット」に対して、少しづつ異なる定義を持っているように思えるし、少なくとも、バージョンコントロールシステムが「チェンジセット機能を持つ」という意味に対して異なる期待を抱いているだろうから。
以後の議論の為に、チェンジセットを簡単に定義しておこう。「チェンジセットとは、一意な名前をもった変更の集合である」。 「変更」には、ファイルコンテンツに対するテキスト的な編集や、ツリー構造に対する修正、また、メタデータに対するちょっとした調整も含まれる。 より一般的に言うならば、チェンジセットとは、あなたが参照できる名前をもったパッチのことだ。
Subversionは、バージョン付けされたツリーを第一階オブジェクトとして扱っており(リポジトリは、ツリーの配列だ)、チェンジセットは(近接のtreeと比較することで得られる)そこからの導出物だ。 ArchやBitkeeperなどのシステムでは、逆の理念の上に作られていて、これらのシステムはチェンジセットを第一階オブジェクトとして管理するように設計されている(リポジトリはパッチの集合体だ)。 ツリーは、パッチの集合を互いに組み合わせることで導出される。
どちらかの哲学が、他方よりも絶対的に素晴しい、というわけではない。 この議論は少なくとも30年は遡れる。 この2つの設計は、ソフトウェア開発のタイプによって、適していたり、そうでなかったりする。 ここでは、この議論を行うのは止めにして、その代わり、Subversionを使ってあなたは何が出来るのか、ということを説明しよう。
Subversionでは、グローバルリビジョン番号「N」は、リポジトリ内のツリーの名前である。 これはN番目のコミットを終えたリポジトリの姿だ。 またこれは暗黙的に一つのチェンジセットの名前にもなる。 もし、ツリーNとツリーN-1を比較すれば、コミットされたパッチそのものを引き出すことが可能だ。
これ故に、「リビジョンN」を、ただツリーとしてだけではなく、チェンジセットとして同様に捉えることも容易い。 もしあなたが要求管理システム(issue tracker)をバグ管理に使っているならば、特定のリビジョン番号を、バグを修正した特定のパッチを参照する為に用いることができる。 例えば、「この問題は、リビジョン9238で修正しました」という具合に。 他の人は 'svn log -r9283' と実行することで、そのバグを修正した完全なチェンジセットに関して読むことが出来るし、'svn diff -r9237:9238'とすれば、パッチそのものを見ることができる。 また、svn の merge コマンドもリビジョン番号を利用する。特定のチェンジセットを、あるブランチから他のブランチへマージするには、そのチェンジセット名を merge の引数へと与えればよい。 'svn merge -r9237:9238 branchURL'は9238番のチェンジセットをあなたの作業コピーへとマージすることになるだろう。
これは、チェンジセットを根源オブジェクトに据えて構築されたシステムみたいに複雑なことは出来ないけれども、でも、CVSよりは凄く便利だよね。
How-to: ¶
Subversion のコードをチェックアウトするにはどうするの? ¶
Subversion クライアントを使おう。
$ svn co http://svn.collab.net/repos/svn/trunk subversion
あなたのローカルマシンにある subversion という名前のディレクトリの中へ Sunversion のソースツリーのコピーがチェックアウトされるよ。
既存のCVSリポジトリを Subversion リポジトリに変換するには? ¶
cvs2svn という変換ツールを試してみて。 これは、 から取得可能だ(機能リストとドキュメントも参照のこと)。 cvs2svn は多くの人々が利用できるように作られてはいるけど、何らかの理由で、このツールがあなたの希望にそぐわないときには、少なくともこれ以外に、2つのツールを試してみることが出来る。
あわせてSubversion linksページも参照のこと。
Proxyサーバに阻まれているんだけどどうしよう? ¶
Subversion クライアントを適切に設定することで、プロキシを超えることが出来るよ。 まずはじめに、「servers」設定ファイルを編集して、どのプロキシサーバを使うか指定しよう。 このファイルが置かれている場所は使っている OS に依存する。 LinuxやUnixでは「~/.subversion」ディレクトリの中に置かれている。 Windowsでは「%APPDATA%\Subversion」中にある(「echo %APPDATA%」を試してみよう。これは隠しディレクトリなので注意)。
このファイルの中には、各要素の説明がコメントとして書かれている。 もしこのファイルが存在しない場合には、最新のSubversionクライアントを入手して、適当なコマンドを実行してみよう。 設定ディレクトリとテンプレートファイルが作成される。
次に、プロキシサーバ自身が、Subversionの利用している全てのHTTPメソッドをサポートしているかどうかを確認する必要がある。 いくつかのプロキシサーバは、標準では、次のメソッド群をサポートしていない: PROPFIND、REPORT、MERGE、MKACTIVITY、CHECKOUT。 一般的に、これを解決する方法、どのプロキシソフトウェアを使っているかに依存する。 例えばSquidでは、設定オプションをこんな風にしてみよう。
# TAG: extension_methods # Squid only knows about standardized HTTP request methods. # You can add up to 20 additional "extension" methods here. # #Default: # none extension_methods REPORT MERGE MKACTIVITY CHECKOUT
(Squid 2.4以降では、PROPFINDについてはすでにサポートされている)。
プロキシサーバへ通過を許可させる、その他HTTPメソッドに関しては、「Subversionが使っている全ての HTTP メソッドは?」も併せて参照のこと。
プロキシに Subversion トラフィックを通過させるのが難しい、または不可能で、でも Subversion のソースコードをチェックアウトしたい場合には、プロキシを迂回することができるかもしれない。 いくつかのプロキシは、80番ポートをフィルタしているにもかかわらず、81番ポートは何でも許可してたりする。このため、svn.collab.net のリポジトリサーバは、80番ポートと同様に81番でも待ち受けている。 というわけで、
svn checkout http://svn.collab.net:81/repos/svn/trunk subversion
を試してみよう。もしかすると、プロキシは素通ししてくれるかもしれない。 別の戦略としては、SSL上でチェックアウトする、というのもあって、多くのプロキシがこれを許可している。
svn checkout https://svn.collab.net/repos/svn/trunk subversion
勿論、あなたの使っている svn クライアントが、SSLサポートを有効にしてビルドされている必要がある。 これには./configureスクリプトへ --with-sslを渡せばよい。 「https」スキームをサポートしているかどうかは、svn --versionで確認することができるよ。
僕の管理者は、Subversion用のHTTPサーバを建てて欲しくないみたいなんだ。それでも僕はリモートから使いたいんだけど、どうしたらいいかな? ¶
簡単な案は、Apache ではなくsvnserveサーバを使うこと。 詳細は、Subversionブックの第6章を参照のこと。
でも、もしあなたの管理者がApacheの実行を認めてくれないんだったら、3690番ポートでカスタムサーバプロセスを実行するのも認めてくれそうにないよね! というわけで、残りの回答は、管理者が既存のSSHインフラを使うことを許可してくれたら、って想定で書きます。
もし、以前にCVSサーバを使っていたのだとすれば、多分、CVSサーバへログインするのに SSH を使っていた筈。 ra_svn Subversion アクセス手法は、Subversion で、これと同等のことを実現するための方法だ。 ただ Subversion リポジトリURLの前に「svn+ssh」を付けるだけで良い。
$ svn checkout svn+ssh://your.domain.com/full/path/to/repository
これにより、SSHプログラムがリモートマシン上でプライベートな「svnserve」プロセスを稼動させ、あなたのUIDによるリポジトリアクセスや、暗号化されたリンク上での情報トンネリングを司ってくれる。
また、これとは別の解決策としては、SSHポートフォワーディングの力を借りて、保護されているサーバへ ra_dav 経由で接続する、というのもある。 SSHを経由することで、ファイアウォールの背後に位置している、Subversion サーバへアクセス可能なマシンへと接続することができるだろう。 SSHサーバが、Subversionのインストールされたサーバと同じでマシンでなくてもよい、という点に注目して欲しい。 もちろん同じでも構わないけど、同じである必要性はない。
まずは、Subversionリポジトリを提供しているHTTPサーバへと接続する為の、ローカルなポートフォワードを作る。 それから、このローカルポートを経由してSubversionサーバへ「接続」する。 これで、リクエストがSSHサーバを経由して、Subversionサーバへ「トンネル」されることになる。
例を示そう。ra_dav の設定された Subversion サーバが、会社のファイアウォールの背後に立っている。 IPアドレスは10.1.1.50 だ(このサーバを、svn-server.example.comと呼ぼう)。 会社は、皆がアクセス可能な ssh-server.example.com 経由でのSSHアクセスを許可している。 内部的には、Subversion リポジトリへ http://svn-server.example.com/repos/ours 経由でアクセスできる。
例: クライアントは、ポートフォワーディングを使ってssh-serverへ接続し、そのポートフォワードを経由して、チェックアウトする。
% ssh -L 8888:svn-server.example.com:80 m% svn checkout http://localhost:8888/repos/ours
svn-server.example.com は、non-trustedユーザによる、非特権ポート上で稼動している httpd インスタンスでも構わないことに注意しよう。 この方法では、Subversion サーバに対して root アクセス権限を必須とはしない。
Joe Orton は以下を注記してくれた。
サーバは、MOVEならびにCOPYリクエストの同期先のヘッダで使われているホスト名に敏感なので、この個所には少し注意を払う必要がある。 この方法を上手く機能させる為には、「ServerAlias localhost」が必要になるかもしれない。
SSHポートフォワーディングに関する幾つかのリンクはこちら。
幾つかの異なるプロジェクトを Subversion で管理するにはどうすれば? ¶
それは取り扱うプロジェクトに依存する。 もしそれらのプロジェクトに関連性があって、データを共有する可能性があるなら、一つのリポジトリ内に幾つかのサブディレクトリを作るという方法が最良だ。 例えばこんな感じ。
$ svnadmin create /repo/svn $ svn mkdir file:///repo/svn/projA $ svn mkdir file:///repo/svn/projB $ svn mkdir file:///repo/svn/projC
もし、それらのプロジェクトが完全に関係性がなく、プロジェクト間でデータを共有する可能性がないのなら、恐らく、独立した無関係のリポジトリを作るのがベストだろう。
$ mkdir /repo/svn $ svnadmin create /repo/svn/projA $ svnadmin create /repo/svn/projB $ svnadmin create /repo/svn/projC
この二つのアプローチの差は、(Ben Collins-Sussman - 最初のケースでは、プロジェクト間でコードのコピーや移動が簡単に実行でき、履歴も保存される(今のところ、'svn cp/mv'は、単一リポジトリの中でしか動作しない)。
- リビジョン番号はリポジトリ全体で共有されるから、最初のケースでは、如何なるプロジェクトに対する単一コミットも、グローバルなリビジョン番号の引き上げが発生する。というわけで、もし、誰かがprojBをチェックアウトしていて、10リビジョンが進んでいることに気がついても、実は、projB自体はちっとも変化していない、ということが起こるわけで、これは、少し奇妙に思えるかもしれない。 まぁ、実際には、大したことないよね。ちょっと不思議な気がするのは、最初だけ。 この現象、rapidsvn が同じリポジトリにあった時には、rapidsvn へのコミットが発生する度に svn で起こっていたことだから :-)。
- 2番目のケースの方が、安全性の維持は簡単になると思う。 Apacheのアクセスコントロールを使うことにより、(ユーザとパーミッションという面で)プロジェクトを互いに隔離することが容易になる。最初のケースでは、リポジトリに対し、プロジェクトを区別するための小さなスクリプトが必要になるだろう(「このユーザは、このディレクトリ以下へのコミットは許可されている?」)。 勿論、この為のスクリプトは提供されているので、それを使うことは可能だよ。
完全に分離している二つのリポジトリをマージするにはどうすればよい? ¶
片方のリポジトリについて、履歴の完全な維持、という点を気にしないのであれば、一つのプロジェクトの下へ単に新しいディレクトリを作った上で、そこへもう片方のデータをインポートすれば良い。
もし、両方のリポジトリの履歴を維持したいのならば、'svnadmin dump'を使って片方のリポジトリのダンプを取り、'svnadmin load'で、そのダンプをもう片方のリポジトリへロードすることになる。 リビジョン番号は変わっちゃうけれど、でも履歴は維持できるよ。
Peter Davis 異なるディレクトリツリーのマージを行うのであれば、CVSモジュールのsvn版を使うことが出来るよ。