マージ操作では、同じオブジェクトの2つのバージョンに別々に行われた変更を結合します。マージは、通常、あるブランチ上で開発を行い、その変更をメインの開発ラインに反映する場合に必要です。
マージ操作には、2つの対象オブジェクト・バージョン(ターゲットおよびソース)が必要で、これらを共通原型バージョンと比較し、内部ルールを使用して、3つのバージョンすべてで見つかった変更に基づく結果を作成します。結果としてターゲット・バージョンが更新されます。これはチェックインされた場合にのみ新しいバージョンとして利用できるようになります。
オブジェクト・バージョンをマージする場合、次のものをマージできます。
1つのオブジェクト・バージョン
複数のオブジェクト・バージョン
マージ操作は、バージョン・コントロール下にあるファイルに対して実行できます。マージ操作で検出された差異および競合は、マージ・ウィンドウに表示されます。マージ・ウィンドウには、アルゴリズムによる選択も表示され、結果が生成される前にそれらの選択を変更できます。
下の図に示されているように、マージ操作には、それぞれが次の役割の1つを果たすオブジェクトが必要です。
ソースとターゲットの2つの対象オブジェクト。ソース・バージョンはチェックイン、ターゲット・バージョンはチェックアウトされている必要があります。
選択された変更が含まれる結果。結果はターゲット・バージョンが更新されたもので、チェックアウトされたままの状態です。このターゲット・バージョンは、ターゲット・オブジェクトのブランチ上に置かれ、チェックインされた場合にのみ、新規バージョンとして使用可能になります。
次の図では、共通原型から派生している2つのブランチを示しています。ブランチにはそれぞれの対象バージョンがあります。最後に、それらが1つの結果にマージされます。
マージ操作には、マージ・アルゴリズムが使用されます。これは、2つのオブジェクト・バージョンと1つの共通オブジェクト・バージョンを比較し、新しい合成バージョンに適用する差異を決定する一連のルールです。アルゴリズムでは、それぞれ任意のブランチにある原型、ソースおよびターゲットは、同じオブジェクトのバージョンであることが必要で、結果は、新規バージョンとしてターゲット・オブジェクトのブランチ上に置かれます。
マージ・アルゴリズムでは、マージ操作に使用されるバージョンの比較単位で処理が行われます。比較単位はオブジェクト・タイプによって異なり、たとえばテキスト・ファイルを処理している場合には新規、変更または削除された行がマージ・アルゴリズムで選択されます。
差異は、共通原型と比較した際に、ソースまたはターゲットで検出された変更点です。差異は、追加、削除または変更のいずれかです。通常、アルゴリズムにより、新規バージョンに反映される正しい選択(解決)が行われます。
特定の比較単位に関して、2つのバージョンが一致した場合、差異は解決されます。しかし、アルゴリズムにより選択されるのは、より多く使用されている単位ではなく、次の表で説明されているように、変更点を表す単位です。3つの単位すべてが同じ場合、解決の必要はありません。競合は、差異がアルゴリズムにより解決できない場合に発生します。
次に、前述の説明を表形式で示します。
マージのソース・バージョンとして選択されたオブジェクト・バージョンに、AとBの2つのテキストが含まれています。ターゲットとして選択されたバージョンは、チェックアウトされ、テキストCが含まれています。アルゴリズムにより共通原型として選択されたバージョンには、テキストCが含まれています。
マージが行われると、チェックアウト済のターゲットは、A、B、Cが含まれるように更新されます。
ここでターゲットをチェックインした場合、新たにチェックインされたバージョンには、A、B、Cが含まれるのに対し、ターゲットの以前のバージョンには依然としてCのみが含まれています。
通常、マージには、子孫ブランチ上のオブジェクトの最新バージョンと、その派生元のブランチ(祖先ブランチ)上のオブジェクトのバージョンが必要で、その結果、祖先ブランチに更新されたバージョンが作成されます。このようなマージの後、子孫ブランチでの開発を続行でき、たとえば、リリースの不具合に対する修正が可能になります。その後、祖先ブランチとのマージを繰り返し行って、さらなる開発を反映させることができます。変更がブランチ階層の両方向に反映されるように、子孫ブランチへのマージを行うこともできます。
マージは、オブジェクトをチェックインすると、自動的に行われる場合があります。オブジェクト・バージョンのチェックインを試みると、オブジェクトがブランチの頂点のものかどうかを判断するチェックが行われます。頂点のものでない場合、そのチェックインが拒否され、ユーザーはマージを行うよう求められます。たとえば、あるオブジェクトの最新バージョンを、ロックせずにチェックアウトしたとします。別のユーザーが、同じバージョンをチェックアウトし、自分がチェックインする前に、そのユーザーが再び元のブランチにチェックインしたとします。この場合、自分のバージョンはすでに頂点バージョンではなく、このバージョンを同じブランチにチェックインできるようにするには、マージを実行する必要があります。