マニュアル

バージョン管理モデル

すべてのバージョン管理システムは、同じ根本的な問題を解決する必要があります。それは、システムがユーザーに情報を共有させる一方で、ユーザーが誤って互いの邪魔をしないようにするにはどうするかということです。ユーザーが誤ってリポジトリ内の互いの変更を上書きしてしまうのは非常に簡単です。

ファイル共有の問題

このシナリオを考えてみましょう。ハリーとサリーという2人の同僚がいるとします。彼らはそれぞれ、同じリポジトリファイルを同時に編集することにしました。もしハリーが最初に自分の変更をリポジトリに保存した場合、(少し後に)サリーが誤って自分の新しいバージョンのファイルでハリーの変更を上書きしてしまう可能性があります。ハリーのバージョンのファイルが永久に失われるわけではありません(システムはすべての変更を記憶しているため)が、ハリーが行った変更は、サリーの新しいバージョンのファイルには含まれていません。なぜなら、サリーはハリーの変更を最初から見ていないからです。ハリーの作業は事実上失われたも同然です。少なくともファイルの最新バージョンからは欠落しており、おそらく偶然によるものです。これは間違いなく避けたい状況です!

図 2.2. 避けるべき問題

The Problem to Avoid

ロック-修正-アンロック方式

多くのバージョン管理システムは、この問題に対処するためにロック-修正-アンロック方式を使用しています。これは非常にシンプルな解決策です。このようなシステムでは、リポジトリは一度に1人だけがファイルを変更することを許可します。まず、ハリーはファイルをロックしてから、変更を開始する必要があります。ファイルをロックすることは、図書館から本を借りるのに似ています。もしハリーがファイルをロックした場合、サリーはファイルに何も変更を加えることができません。もしサリーがファイルをロックしようとすると、リポジトリは要求を拒否します。彼女ができることは、ファイルを読み、ハリーが変更を終えてロックを解除するのを待つことだけです。ハリーがファイルのロックを解除すると、彼の順番は終わり、今度はサリーがロックして編集することで自分の順番を取ることができます。

図 2.3. ロック-修正-アンロック方式

The Lock-Modify-Unlock Solution

ロック-修正-アンロック方式の問題点は、少し制約が強く、しばしばユーザーにとって障害になることです。

  • ロックは管理上の問題を引き起こす可能性があります。 ハリーがファイルをロックしたまま忘れてしまうことがあります。その間、サリーはまだファイルを編集するのを待っているので、身動きが取れません。そして、ハリーは休暇に行ってしまいます。今、サリーは管理者にハリーのロックを解除してもらう必要があります。この状況は、多くの不必要な遅延と時間の浪費を引き起こすことになります。

  • ロックは不必要なシリアライズを引き起こす可能性があります。 ハリーがテキストファイルの先頭を編集していて、サリーが同じファイルの末尾を編集したいだけの場合はどうでしょうか?これらの変更はまったく重複していません。彼らは簡単に同時にファイルを編集でき、変更が適切にマージされれば大きな問題は起こらないでしょう。このような状況で彼らが順番に作業する必要はありません。

  • ロックは誤った安心感を生み出す可能性があります。 ハリーがファイルAをロックして編集し、サリーが同時にファイルBをロックして編集すると仮定します。しかし、AとBが互いに依存しており、それぞれの変更が意味的に非互換であるとします。すると突然、AとBは一緒に動作しなくなります。ロックシステムは問題を防止する力はありませんでしたが、なぜか誤った安心感を提供していました。ハリーとサリーは、ファイルをロックすることで、それぞれが安全で隔離されたタスクを開始していると想像しやすく、そのため、早期に非互換な変更について話し合うことを抑制してしまいます。

コピー-修正-マージ方式

Subversion、CVS、およびその他のバージョン管理システムは、ロックの代替としてコピー-修正-マージ方式を使用しています。このモデルでは、各ユーザーのクライアントはリポジトリを読み取り、ファイルまたはプロジェクトの個人的なワーキングコピーを作成します。ユーザーは並行して作業し、自分のプライベートコピーを変更します。最後に、プライベートコピーはマージされて新しい最終バージョンになります。バージョン管理システムはしばしばマージを支援しますが、最終的には人間がそれを正しく行う責任があります。

例を挙げます。ハリーとサリーがそれぞれ、リポジトリからコピーされた同じプロジェクトのワーキングコピーを作成するとします。彼らは同時に作業し、自分のコピー内の同じファイルAに変更を加えます。サリーが最初に自分の変更をリポジトリに保存します。ハリーが後で自分の変更を保存しようとすると、リポジトリは彼のファイルAが古いことを通知します。言い換えれば、リポジトリ内のファイルAは、彼が最後にコピーしてから何らかの形で変更されたということです。そこでハリーはクライアントに、リポジトリからの新しい変更をファイルAのワーキングコピーにマージするように依頼します。サリーの変更は彼の変更と重複していない可能性が高いです。したがって、両方の変更セットを統合すると、彼はワーキングコピーをリポジトリに保存し直します。

図 2.4. コピー-修正-マージ方式

The Copy-Modify-Merge Solution

図 2.5. ...コピー-修正-マージ方式(続き)

...Copy-Modify-Merge Continued

しかし、サリーの変更がハリーの変更と重複する場合はどうなるでしょうか?その場合はどうなるのでしょうか?この状況はコンフリクトと呼ばれ、通常はそれほど問題ではありません。ハリーがクライアントに最新のリポジトリの変更をワーキングコピーにマージするように依頼すると、彼のファイルAのコピーは何らかの形でコンフリクト状態としてフラグが立てられます。彼は両方の競合する変更セットを確認し、それらの間で手動で選択できるようになります。ソフトウェアはコンフリクトを自動的に解決できないことに注意してください。必要なインテリジェントな選択を理解し、行うことができるのは人間だけです。ハリーが重複する変更を手動で解決したら(おそらくサリーとコンフリクトについて話し合うことで!)、マージされたファイルを安全にリポジトリに保存し直すことができます。

コピー-修正-マージ方式は少し混沌としているように聞こえるかもしれませんが、実際には非常にスムーズに動作します。ユーザーは並行して作業でき、互いに待つ必要はありません。彼らが同じファイルで作業する場合、彼らの同時変更のほとんどはまったく重複しないことが判明します。コンフリクトはまれです。そして、コンフリクトを解決するのにかかる時間は、ロックシステムによって失われる時間よりもはるかに少ないです。

結局のところ、すべては1つの重要な要素、つまりユーザー間のコミュニケーションに帰着します。ユーザー間のコミュニケーションが不十分な場合、構文的および意味的なコンフリクトが増加します。システムはユーザーに完璧なコミュニケーションを強制することはできず、システムは意味的なコンフリクトを検出することはできません。したがって、ロックシステムがどうにかしてコンフリクトを防ぐという誤った約束に惑わされるのは無意味です。実際には、ロックは生産性を阻害するだけのようです。

ロック-修正-アンロック方式が優れている一般的な状況が1つあります。それは、マージできないファイルがある場合です。たとえば、リポジトリにいくつかのグラフィックイメージが含まれており、2人が同時にイメージを変更すると、それらの変更をマージする方法はありません。ハリーまたはサリーのどちらかが変更を失うことになります。

Subversionの動作

Subversionはデフォルトでコピー-修正-マージ方式を使用しており、多くの場合、これで十分です。ただし、バージョン1.2以降、Subversionはファイルロックもサポートしているため、マージできないファイルがある場合、または経営陣によってロックポリシーを強制されている場合でも、Subversionは必要な機能を提供します。

TortoiseSVN ホームページ