この章では、ワークスペース間でのファイルのコピーや衝突の解決を行うときに、ワークスペース管理ツールが SCCS 履歴ファイルをどのように処理するかについて説明します。
この章は、以下の節で構成されています。
ここでの説明は、読者がブランチ (分岐) の概念など SCCS について理解していることを前提にしています。SCCS についての詳細は、『Programming Utilities Guide』を参照してください。
ブリングオーバーやプットバックのトランザクションでは、ソースファイルは SCCS デルタから得られ、SCCS デルタ ID (SID) によって特定されています。これらのトランザクションでファイルをコピーする場合、ワークスペース管理ツールはそのファイルの SCCS 履歴ファイル (s ドットファイル) を処理しなければなりません。
ブリングオーバーやプットバックのトランザクションによってソースワークスペースから宛先ワークスペースにファイルをコピーすると、表面的にはファイルが 1 つ転送されただけのように見えますが、実際にはそのファイルに関するすべての SCCS 情報 (デルタやコメントなど) を宛先の SCCS 履歴ファイルにマージしなければなりません。この情報をソースから宛先の履歴ファイルにマージすることによって、現行バージョンのデルタが得られ、そのファイルの全デルタおよびコメント履歴が得られます。ただし、宛先のワークスペースにそのファイルが存在する場合に限ります。存在しない場合、履歴ファイルがそのままソースから宛先にコピーされます。
宛先ワークスペースのファイルを更新する場合 (つまり、ブリングオーバーまたはプットバックトランザクションのソース側でファイルが変更されていて、宛先側では変更されていない場合)、新しいデルタが宛先の履歴ファイルに追加されます。この場合、SCCS 履歴ファイルがソースから宛先にコピーされるのではなくマージされる理由は、宛先の履歴ファイルに格納されているフラグやアクセスリストなどの管理情報を保持しておくためです。
ワークスペース管理ツールはデルタ履歴の分岐箇所を判別し、その分岐の発生以後にソースワークスペースで作成されたデルタのみを宛先ワークスペースに追加します。履歴の分岐箇所を判別するために、親と子の履歴ファイルのデルタテーブルを比較します。この比較に使用される情報には、該当デルタがいつ誰によって作成されたかといったデータやコメントが含まれています。図 9-1 に、プットバックトランザクションで子ワークスペースのデルタ 1.3 と 1.4 を親ワークスペースの SCCS 履歴ファイルに追加する例を示します。
親と子の間でファイルをコピーする場合、それぞれのファイルのバージョンが最後に更新されてから変更されていることがあります。このような場合、親と子のファイルに「衝突」が存在すると言います。
ファイルに衝突が存在すると、ワークスペース管理ツールはそれぞれのファイルに加えられた変更の矛盾をユーザーが効率的に解決できるよう支援し、それらのファイルのデルタ、管理情報、コメント履歴を保持しようとします。ワークスペース管理ツールは、親の SCCS デルタを子の履歴ファイルにマージします。次に、衝突解決トランザクションによって子の側でこの衝突を解決します。衝突解決についての詳細は、第 8 章「衝突の解決」を参照してください。
ここであげる例では、1 つの統合ワークスペースとそれぞれ別の開発者が所有する 2 つの子ワークスペースを使用しています。2 人の開発者はそれぞれ、統合ワークスペースから同じファイルをコピーし、このファイルに独自の変更を加えています。この例で、衝突が発生したときに、それらを解決するためにワークスペース管理ツールが SCCS ファイルをどのように処理するかを説明します。なお、例を解釈するにあたり次の点に留意してください。
デフォルトのデルタ (次のデルタが SCCS デルタツリーに追加されるポイント) は、次の記号に接続されていない下方向の線で表わしています。
バージョン管理ツールを使用すると、SCCS デルタツリーを図に表示することができます。
開発者はそれぞれ、ブリングオーバートランザクションにより統合ワークスペースから同じファイルをコピーします。このファイルは両開発者のワークスペースでは新規のものであるため、 SCCS 履歴ファイルは両ワークスペースにコピーされます。
開発者 B は、このファイルに変更を加えて、 2 つの新しいデルタ 1.3 と 1.4 を作成した後、ファイルを統合ワークスペースに戻します (プットバックトランザクションを実行します)。このときワークスペース管理ツールは、2 つの新しいデルタを親の SCCS デルタツリーに追加します。
アクセスリストなどの管理情報を保持しておくため、宛先ワークスペース側の SCCS 履歴ファイルをソース側のファイルと置き換えるという方法はとらずに、新しいデルタが宛先の SCCS 履歴ファイルに追加されます。
一方、開発者 A も、コピーしてきた同じファイルに独自の変更を加え (3 つの新しいデルタ 1.3、1.4、および 1.5 を作成します)、ファイルを統合ワークスペースに戻そうとしています。
しかし、ここでプットバックトランザクションの実行を許可すると、開発者 B がプットバックした変更が消されてしまうため (ファイルの衝突) 、ワークスペース管理ツールは、プットバックトランザクションの実行要求を拒否します。そこで、開発者 A はプットバックの前に、開発者 B による変更内容を自分のファイルに組み込まなければなりません。
開発者 A は、この時点で開発者 B による変更を含むファイルを統合ワークスペースから自分のワークスペースにコピーします。このとき、開発者 B によって作成されたデルタが、開発者 A の SCCS 履歴ファイルに追加されます。
なお、親からコピーされるデルタツリー自体は子の側では変更されません。子において作成された新しいデルタが SCCS ブランチとして、子と親に共通する最新のデルタに追加され、それぞれ新しい SID が割り当てられます。これらのデルタには、デルタの分岐点から SID を生成する SCCS ブランチ番号付けアルゴリズムによって新しい番号が付けられます。この例では、ブランチは SID 1.2 に追加され、最初のデルタの番号は 1.2.1.1 になります。また、子の側で作成された最新のデルタ (1.2.1.3、ブランチになる前の 1.5) はその後もデフォルトのデルタとして扱われます。したがって、開発者 A が衝突の解決以前に子ワークスペースで作成した新しいデルタはすべて、子のブランチツリーに追加され、親の基幹ツリーには追加されません。
開発者 A は、自分のワークスペースで衝突解決トランザクションを使用して衝突を解決します (衝突解決についての詳細は、第 8 章「衝突の解決」を参照してください)。開発者 A は衝突解決トランザクションを使用して、SID 1.2.1.3 と 1.4 で表わされるそれぞれのファイルバージョンをどのようにマージするかを決定します。開発者 A が変更を適用すると、衝突解決トランザクションは新たにマージされた内容を新しいデルタ (1.5) に格納します。
新しいデルタ 1.5 をこのように丸で囲んで表現しているのは、これが開発者 A によって作成されたものであることを示すためです。
新たに作成されたデルタは、この時点で、開発者 A が次に行う変更内容が追加されるデフォルトの位置になります。
以上でファイルの衝突が解決されたので、開発者 A は自分の最新のファイルを統合ワークスペースにプットバックすることができます。このとき、ブランチと新たに作成されたデルタは、統合ワークスペースの SCCS 履歴ファイルに追加されます。
開発者 B は、自分のワークスペースでファイルに次の変更を行います。この結果、デルタ 1.5 が作成されます。続いて、この新しい変更を統合ワークスペースにプットバックしようとしますが、開発者 A がその前に統合ワークスペースに戻した新しいデルタ 1.5 と内容が異なるため、このトランザクションの実行は許可されません。
開発者 B は、開発者 A が統合ワークスペースに戻した変更ファイルを自分のワークスペースにコピーします。ここで、このファイルのデルタは、ワークスペース管理ツールによって開発者 B のワークスペースの SCCS 履歴ファイルに追加され、番号が付けなおされます。
前述のケースと同様、ワークスペース管理ツールは開発者 B が作成したデルタを基幹デルタツリーの最新の共通デルタにブランチとして追加し、該当する番号が付けなおされます。1.5 が 1.4.1.1 になります。衝突が解決される以前に開発者 B のワークスペースで新しいデルタが作成されていれば、それらのデルタはこのブランチに追加されます。
開発者 B は、衝突解決トランザクションを使用して、1.5 と 1.4.1.1 との相異をマージして衝突を解決し、新しいデルタ 1.6 を作成します。
マージされた新しい変更内容は、新しいデルタとして親デルタ 1.6 に追加されます。
新しいデルタは、そのワークスペースのオーナーである開発者によって所有されます。
新しいデルタはデフォルトのデルタになるため、子ワークスペースで以後行われる変更の結果はすべて、このデルタの下に追加されることになります。