どのバージョン管理システムでも、根本的な問題を解決しなければなりません。それは、どのようにユーザーに情報の共有をさせつつ、偶然にも他人の邪魔をしないようにするかです。リポジトリ内の他人の変更を、誤って上書きしてしまうことは容易に起こりうることです。
次のような場面を想像してみてください。2人の同僚、ハリーとサリーがいたとします。2人は同時に同じリポジトリ内のファイルを編集しようとしています。始めにハリーが変更を保存してから、(数分後に)サリーが自分の新しいファイルを偶然にも上書きする可能性があります。(システムが変更を記憶しているので)ハリーのバージョンが永遠に失われるわけではありませんが、ハリーが行った変更はサリーの新バージョンに隠されて見えなくなります。サリーがハリーの変更を取り込まなかったからです。おそらく事故でですが、ハリーの作業は事実上失われたり、少なくとも後のバージョンのファイルには現れなくなったりします。これは確実に回避しなければならな状況です。
多くのバージョン管理システムでは、ロック・変更・アンロックモデルというとても単純な方法で、この問題に対処しています。このようなシステムでは、リポジトリはひとつのファイルにつき同時に一人しか変更できないようにしています。この場合、ハリーは変更を加える前にあらかじめロックをしなければなりません。ファイルをロックすることは、図書館から本を貸りるようなものです。ハリーがファイルにロックをかけると、サリーはそこに変更を加えられなくなります。サリーがファイルをロックしようとしても、リポジトリはその要求を拒否します。できるのは、ファイルを読むことと、ハリーが変更を終えてロックを解除するのを待つことだけです。ハリーが変更を終えてロックを解除すると、サリーはロックして編集できるようになります。
ロック・変更・アンロックモデルの問題点は、少々制限が厳しいことで、しばしばユーザーの作業の邪魔になります。
ロックは管理上の問題を起こす可能性があります。ハリーは、ファイルをロックしたまま忘れてしまうかもしれません。いっぽうサリーは、ファイルが編集できるようになるのをずっと待っていて、その間何もできません。ハリーが休暇を取ってしまったりすると、サリーは管理者にハリーのロックを解除してもらわなければなりません。この状況では不要な遅れと、時間の浪費が発生します。
ロックは不必要な作業待ちを発生させる可能性があります。ハリーがテキストファイルの先頭を編集していて、サリーは同じファイルの最後を編集したいだけだとしたらどうでしょう。変更は全く重なることがありません。簡単にファイルを同時に編集でき、互いを適切にマージできるとすれば、なんの障害も発生しないでしょう。この状況では待つ必要はないはずです。
ロックは誤った安心感を与える可能性があります。ハリーがファイルAをロックして編集し、サリーがファイルBをロックして編集するとします。しかし、AとBが互いに依存しあっている場合、変更すると意味的な矛盾が発生します。突然AとBが一緒には動作しなくなります。ロック方式のシステムはこの問題に対して無力です。ある意味、誤った安心感を与えていると言えるでしょう。ハリーもサリーもファイルをロックしたことで安全な状態に入ったと感じ、自分の作業が保護されていると錯覚してしまうのです。
Subversion や CVS などのバージョン管理システムは、ロックの代わりに コピー・変更・マージ モデルを使用します。このモデルでは、ユーザーのクライアントが個別にリポジトリを読み込み、ファイルやプロジェクトの個人的な 作業コピー を作成します。そこからユーザーは並行して作業し、個人のコピーを変更します。最後に個人のコピーを新しい最終版にマージします。バージョン管理システムはマージの補助を行いますが、正しくマージする最終責任は人間が負うことになります。
例を挙げましょう。ハリーとサリーがそれぞれ同じプロジェクトの作業コピーを、リポジトリからコピーして作成したとします。2人とも同時に作業し、それぞれのコピーの同じファイル A
に変更を加えました。先にサリーがリポジトリに変更を保存します。そのあとハリーが変更を適用しようとしますが、ハリーのファイル A は最新ではないとリポジトリに言われてしまいます。一方、リポジトリのファイル A には、ハリーが最後にコピーしたときから、何らかの変更が加わっています。そこでハリーは、リポジトリから新しい変更点を取得し、作業コピーのファイル A にマージするように指示を出します。幸い、サリーの変更はハリーの変更に重なりません。そのため、いったん両方の変更点を統合してしまえば、作業コピーの内容をリポジトリに書き戻すことができます。
では、サリーの変更がハリーの変更に重なっていたら?そのときはどうなるのでしょう?この状況は競合と呼ばれ、ふつうは多発するものではありません。ハリーがクライアントプログラムに、リポジトリの最新の変更を自分の作業コピーにマージするよう指示を出すと、作業コピーのファイル A は競合している状態になります。このとき彼は競合した変更を両方とも見ることができ、どちらを採用するかを選択することができます。ソフトウェアは自動的に競合を解決できないことに注意してください。理解し正しく選択する力を持っているのは人間だけです。ハリーがいったん重なった変更を解決したら、(おそらくサリーと競合について話し合ったあとで)マージしたファイルを安全にリポジトリに保存できます。
コピー・変更・マージモデルは少々無秩序に見えますが、実際にはとてもスムーズに事が進みます。ユーザーは他の人を待つこともなく、並行して作業を進められます。同じファイルに対して作業を行った場合でも、ほとんどの変更は重ならないことが分かると思います。そして、競合を解決するのにかかる時間は、ロックシステムで失われる時間よりもずっと少ないのです。
このことは、最終的にひとつの重要な要因にたどり着きます。ユーザー間のコミュニケーションです。ユーザーがお互いに意見をやりとりしなければ、構文上・意味上の競合が増えていきます。どんなシステムもユーザーに完璧なコミュニケーションを強要できませんし、意味上の競合も検出できません。したがって、ロックシステムなら競合は防げるなどという間違った思い込みで安心するなど、全く意味がありません。実際には、ロックは生産性を下げる以外の何物でもないように思えます。
ロック・変更・アンロックモデルの方がよいといわれる事例もあります。マージできないファイルがある場合です。例えば、リポジトリに画像イメージが含まれている場合、2人が同時にイメージを変更してもこれをマージする方法はありません。ハリーとサリーのどちらも自分の行った変更を失ってしまいます。