ワーキングコピーについては既にお読みになったことでしょう。ここでは、Subversion クライアントがどのようにワーキングコピーを作成し、使用するかを説明します。
Subversion のワーキングコピーは、ローカルシステム上の通常のディレクトリツリーであり、ファイルの集まりを含んでいます。これらのファイルは自由に編集でき、ソースコードファイルであれば、通常の方法でプログラムをコンパイルできます。ワーキングコピーはあなた個人の作業領域です。Subversion は、あなたが明示的に指示しない限り、他の人の変更を取り込んだり、あなた自身の変更を他の人が利用できるようにしたりすることはありません。
ワーキングコピー内のファイルをいくつか変更し、それらが正しく動作することを確認したら、Subversion は、プロジェクトで一緒に作業している他の人に変更を公開する(リポジトリに書き込むことによって)ためのコマンドを提供します。他の人が自分の変更を公開した場合、Subversion は、それらの変更をワーキングディレクトリにマージする(リポジトリから読み取ることによって)ためのコマンドを提供します。
ワーキングコピーには、これらのコマンドを実行するのに役立つ、Subversion によって作成および管理されるいくつかの追加ファイルも含まれています。特に、ワーキングコピーには、.svn
という名前のサブディレクトリが含まれており、ワーキングコピーの管理ディレクトリとも呼ばれます。この管理ディレクトリ内のファイルは、Subversion が、どのファイルに未公開の変更が含まれているか、どのファイルが他の人の作業に関して古くなっているかを認識するのに役立ちます。1.7 より前の Subversion では、ワーキングコピーのバージョン管理されたすべてのディレクトリに .svn
管理サブディレクトリが保持されていました。Subversion 1.7 では、まったく異なるアプローチが採用され、各ワーキングコピーには、そのワーキングコピーのルートの直下の子である管理サブディレクトリが 1 つだけになりました。
一般的な Subversion リポジトリは、多くの場合、いくつかのプロジェクトのファイル(またはソースコード)を保持しています。通常、各プロジェクトはリポジトリのファイルシステムツリー内のサブディレクトリです。この構成では、ユーザーのワーキングコピーは通常、リポジトリの特定のサブツリーに対応します。
たとえば、2 つのソフトウェアプロジェクトを含むリポジトリがあるとします。
言い換えれば、リポジトリのルートディレクトリには、paint
と calc
の 2 つのサブディレクトリがあります。
ワーキングコピーを取得するには、リポジトリのサブツリーをチェックアウトする必要があります。(「チェックアウト」という用語は、リソースのロックまたは予約に関係があるように聞こえるかもしれませんが、そうではありません。単にプロジェクトのプライベートコピーを作成するだけです。)
button.c
を変更したとします。.svn
ディレクトリはファイルの変更日と元の内容を記憶しているため、Subversion はファイルが変更されたことを認識できます。ただし、Subversion は、あなたが明示的に指示するまで、変更を公開しません。変更を公開する行為は、一般的にリポジトリへのコミット(またはチェックイン)として知られています。
変更を他の人に公開するには、Subversion の commit コマンドを使用できます。
これで、button.c
への変更がリポジトリにコミットされました。別のユーザーが /calc
のワーキングコピーをチェックアウトすると、ファイルの最新バージョンで変更を確認できます。
あなたと同じタイミングで /calc
のワーキングコピーをチェックアウトした共同作業者サリーがいるとします。button.c
への変更をコミットすると、サリーのワーキングコピーは変更されません。Subversion は、ユーザーのリクエストに応じてのみワーキングコピーを変更します。
サリーがプロジェクトを最新の状態にするには、Subversion の update コマンドを使用して、ワーキングコピーを更新するように Subversion に依頼できます。これにより、あなたの変更が彼女のワーキングコピーに組み込まれるだけでなく、彼女がチェックアウトしてからコミットされた他の変更も組み込まれます。
サリーは、更新するファイルを指定する必要がないことに注意してください。Subversion は、.svn
ディレクトリの情報と、リポジトリ内の追加情報を使用して、最新の状態にする必要のあるファイルを決定します。
Subversion リポジトリには、ローカルディスク上、またはさまざまなネットワークプロトコルを介して、さまざまな方法でアクセスできます。ただし、リポジトリの場所は常に URL です。URL スキーマはアクセス方法を示します
表2.1 リポジトリアクセス URL
スキーマ | アクセス方法 |
---|---|
file://
| ローカルまたはネットワークドライブ上のリポジトリへの直接アクセス。 |
http://
| Subversion 対応の Apache サーバーへの WebDAV プロトコル経由のアクセス。 |
https://
| http:// と同じですが、SSL 暗号化を使用します。 |
svn://
| svnserve サーバーへのカスタムプロトコル経由の認証なしの TCP/IP アクセス。 |
svn+ssh://
| svnserve サーバーへのカスタムプロトコル経由の認証済み、暗号化された TCP/IP アクセス。 |
ほとんどの場合、Subversion の URL は標準構文を使用しており、URL の一部としてサーバー名とポート番号を指定できます。file://
アクセス方法は通常、ローカルアクセスに使用されますが、ネットワーク化されたホストへの UNC パスでも使用できます。したがって、URL は file://hostname/path/to/repos
の形式になります。ローカルマシンでは、URL の hostname
部分は、存在しないか localhost
である必要があります。このため、ローカルパスは通常、3 つのスラッシュ file:///path/to/repos
で表示されます。
また、Windows プラットフォームで file://
スキームを使用するユーザーは、クライアントの現在の作業ドライブとは異なるドライブ上にあるリポジトリにアクセスするために、非公式の「標準」構文を使用する必要があります。次の 2 つの URL パス構文のいずれかが機能します。ここで、X
はリポジトリが存在するドライブです
file:///X:/path/to/repos ... file:///X|/path/to/repos ...
URL は、Windows でのパスのネイティブ(非 URL)形式がバックスラッシュを使用している場合でも、通常のスラッシュを使用することに注意してください。
FSFS リポジトリにはネットワーク共有経由でアクセスできますが、これにはさまざまな理由から推奨されません
すべてのユーザーに直接書き込みアクセス権を与えているため、誤ってリポジトリファイルシステムを削除または破損させる可能性があります。
すべてのネットワークファイル共有プロトコルが、Subversion が必要とするロックをサポートしているわけではありません。いつか、リポジトリが微妙に破損していることに気付くでしょう。
アクセス許可を適切な方法で設定する必要があります。SAMBA はこの点で特に困難です。
ある人が新しいバージョンのクライアントをインストールしてリポジトリ形式をアップグレードすると、他のすべての人は、新しいクライアントバージョンにアップグレードするまでリポジトリにアクセスできなくなります。
svn commit 操作は、任意の数のファイルとディレクトリへの変更を単一のアトミックトランザクションとして公開できます。ワーキングコピーでは、ファイルの内容を変更したり、ファイルとディレクトリを作成、削除、名前変更、コピーしたりしてから、変更の完全なセットをユニットとしてコミットできます。
リポジトリでは、各コミットはアトミックトランザクションとして扱われます。すべてのコミット変更が行われるか、何も行われないかのいずれかです。Subversion は、プログラムのクラッシュ、システムのクラッシュ、ネットワークの問題、および他のユーザーのアクションに直面しても、この原子性を保持します。
リポジトリがコミットを受け入れるたびに、これはファイルシステムツリーの新しい状態を作成します。これはリビジョンと呼ばれます。各リビジョンには、一意の自然数が割り当てられ、前のリビジョンの数より 1 つ大きくなります。新しく作成されたリポジトリの最初のリビジョンはゼロと番号付けされ、空のルートディレクトリのみで構成されています。
リポジトリを視覚化するのに最適な方法は、一連のツリーとして捉えることです。0 から始まり、左右に伸びるリビジョン番号の配列を想像してください。各リビジョン番号の下にはファイルシステムツリーがぶら下がっており、各ツリーは各コミット後のリポジトリの外観の「スナップショット」です。
ワーキングコピーは、リポジトリ内の単一のリビジョンに常に一致するとは限らないことに注意することが重要です。それらは、いくつかの異なるリビジョンのファイルを含む場合があります。たとえば、最新リビジョンが 4 のリポジトリからワーキングコピーをチェックアウトするとします
calc/Makefile:4 integer.c:4 button.c:4
現時点では、このワーキングディレクトリはリポジトリのリビジョン 4 と正確に対応しています。ただし、button.c
に変更を加えてコミットするとします。他のコミットが行われていないと仮定すると、コミットによってリポジトリのリビジョン 5 が作成され、ワーキングコピーは次のようになります
calc/Makefile:4 integer.c:4 button.c:5
この時点で、サリーが integer.c
に変更をコミットし、リビジョン 6 を作成するとします。svn update を使用してワーキングコピーを最新の状態にすると、次のようになります
calc/Makefile:6 integer.c:6 button.c:6
サリーによる integer.c
の変更がワーキングコピーに表示され、変更は button.c
にまだ存在します。この例では、Makefile
のテキストはリビジョン 4、5、および 6 で同一ですが、Subversion はワーキングコピーの Makefile
をリビジョン 6 でマークして、それがまだ最新であることを示します。したがって、ワーキングコピーの最上位でクリーンアップデートを実行すると、通常はリポジトリ内の正確に 1 つのリビジョンに対応します。
ワーキングディレクトリ内の各ファイルについて、Subversion は .svn/
管理領域に 2 つの重要な情報を記録します
ワーキングファイルが基づいているリビジョン(これはファイルのワーキングリビジョンと呼ばれます)、および
ローカルコピーがリポジトリによって最後に更新された日時を記録するタイムスタンプ。
この情報が与えられると、リポジトリと通信することにより、Subversion はワーキングファイルが次の 4 つの状態のどれにあるかを判断できます
ファイルはワーキングディレクトリ内で変更されておらず、そのファイルのワーキングリビジョン以降、そのファイルへの変更はリポジトリにコミットされていません。ファイルの commit は何もせず、ファイルの update は何も行いません。
ファイルはワーキングディレクトリ内で変更されており、そのベースリビジョン以降、そのファイルへの変更はリポジトリにコミットされていません。リポジトリにコミットされていないローカルの変更があるため、ファイルの commit は変更の公開に成功し、ファイルの update は何も行いません。
ファイルはワーキングディレクトリ内で変更されていませんが、リポジトリ内で変更されています。ファイルは最終的に更新して、公開リビジョンと最新の状態にする必要があります。ファイルの commit は何もせず、ファイルの update は最新の変更をワーキングコピーに組み込みます。
ファイルはワーキングディレクトリとリポジトリの両方で変更されています。ファイルの commit は、古いエラーで失敗します。ファイルは最初に更新する必要があります。update コマンドは、公開の変更とローカルの変更をマージしようとします。Subversion がマージを自動的に妥当な方法で完了できない場合、ユーザーが競合を解決するように任せます。