
ブランチおよびマージの操作方法
2つのコードライン間で変更をマージする方法
プロジェクト1のコードラインが、PERFORCEにおいて //depot/project1 に格納されているとします。ここで、プロジェクト1から派生するプロジェクト2がスタートするため、プロジェクト1・コードラインをプロジェクト2・コードラインへブランチする必要があり、これを //depot/project2 に格納します。この時点では、プロジェクト2・コードラインはプロジェクト1・コードラインとまったく同じ内容を持っています。しかし、時間の経過とともにこれらは変更(同一ファイルに対して異なる変更、異なるファイルが追加/削除、等)されます。さらには、プロジェクト2からプロジェクト1(またはその逆)へ変更をマージする必要が発生するでしょう
まず初めに、 //depot/project2 のマッピングがクライアント・ビューに記述されているかどうかを確認する必要があります。ブランチ元のファイルについては必ずしもマッピングされている必要はありませんが、ブランチ先のファイルについては必ずマッピングされている必要があります。クライアント仕様は、例えば次のようになっていることになります。:
Client: lion
Root: c:\workspace
View:
//depot/project2/... //lion/project2/...
次に、プロジェクト1とプロジェクト2の関係を定義するためにブランチ仕様を作成します。(ブランチ仕様は必須ではありません。実際に、簡単なケースでは必要としませんが、ご紹介するという意味で以下に示します。)
ブランチ仕様の名前を "p1p2" とし、次のコマンドで作成します。
p4 branch p1p2
p4 branchコマンドは、p4 clientコマンドと同様にフォームを起動します。フォームを編集することによって、このブランチ仕様を使用したときに //depot/project1 のファイルが //depot/project2 へマッピングされるよう、"View:" フィールドを書き換えます。:
Branch: p1p2
View:
//depot/project1/... //depot/project2/...
新しいコードラインをブランチするには、反映(integrate)およびサブミット(submit)という2つの手順を踏みます。もし将来的に実施するマージのためにプロジェクト1・コードラインとプロジェクト2・コードラインに関係を持たせたいのであれば、この方法でプロジェクト2・コードラインを作成しなければなりません。(「ブランチすること」と「プロジェクト2用のディレクトリを作成し、プロジェクト1からファイルをコピーし、それらをディポに新規登録すること」とは同じではありません。そのように操作することもできますが、それではPERFORCEサーバが反映の履歴を持つことができませんので、プロジェクト間でマージを行うことが非常に困難になります。)
ブランチ仕様を用いることで、どのようにブランチ(反映)するかをp4 integrate コマンドに指定することができます。:
p4 integrate -b p1p2
反映操作(p4 integrate)は、 //depot/project1 から当該クライアント・ワークスペースへすべてのファイルをコピーし、それらを //depot/project2 配下において反映目的(branch)の作業状態にします。作業状態になったファイルをサブミットすると、プロジェクト2のファイルがディポに作成され、 //depot/project2 配下のファイルは //depot/project1 配下にある特定のリビジョンからブランチされているという事実が、PERFORCEによって記録されます。 反映操作(p4 integrate)の実行結果は、次のようになります。:
//depot/project2/a.c#1
- branch from //depot/project1/a.c#1
//depot/project2/b.c#1
- branch from //depot/project1/b.c#1
...など
これを実行すると、作業状態になったファイルをサブミットすることができます。:
p4 submit
これによりサブミットのフォームがエディタで立ち上がりますので、コメント(Description:)を記入してエディタを閉じます。
ここで、プロジェクト2のファイルに変更を加えることになったとしましょう。これを実施するためには、クライアント・ビューにおいて //depot/project2 のパスが指定されていなければなりませんが、これは既に指定されているはずです。ファイルを変更するために、マッピングされているクライアント・ワークスペースのディレクトリに移動します。
cd c:\workspace\project2
ここでは、次のような変更(ファイルの編集、削除、追加)を行ったとして説明します。:
p4 edit a.c
(a.cはもともと空のファイルで、新しい行 "abc" を追加しました。)
p4 delete b.c
p4 add c1.c
これらの変更が完了したら、そのチェンジリストをサブミットします。
p4 submit
一方、プロジェクト1のファイルに変更を加えたい場合は、クライアント・ビューに //depot/project1 のファイルを記述する必要があります。つまり、p4 clientを実行してクライアント仕様を編集し、"View:" フィールドに次の行を追加します。
//depot/project1/... //lion/project1/...
例えば、 //depot/project1/a.c を編集します。(ここでは、プロジェクト2のファイルに対して行った先ほどの編集に対して、あえて衝突(conflict)を発生させるようにします。)
cd c:\workspace\project1
p4 edit a.c
(a.cはもともと空のファイルで、新しい行 "def" を追加しました。)
p4 submit
それでは、マージ操作を実行します。今、a.c についてはプロジェクト1とプロジェクト2の両方で変更をかけたことがわかっていますが、ここではプロジェクト1での変更をプロジェクト2にマージさせます。この操作は、 反映(integrate)、衝突解決(resolve)、サブミット(submit)の3つのステップで行います。まず、反映については次のとおりです。
p4 integrate -b p1p2
このコマンドによって、最後に反映を行った後に変更されたプロジェクト1内のファイルが検出され、それに対応するプロジェクト2内のファイルが作業状態になります。このケースでは、ただ1つのファイルがそれに該当し、コマンドの出力は次のとおりです。
//depot/project2/a.c#1
- integrate from //depot/project1/a.c#2
これにより、衝突解決(p4 resolveコマンド)を実行する準備が整いました。このコマンドを実行することにより、マージ元からマージ先へどのように変更を伝えるかを、PERFORCEサーバに指示します。:
p4 resolve
p4 resolveコマンドは、衝突解決が必要なそれぞれのファイルに対してプロンプトを表示し、どのように解決するかの提案を示します。ここでは、a.c のマージを行う際に衝突(conflict)が発生しますので、p4 resolveが示す提案は「編集すること(e)」となります。
c:\workspace\project2\a.c - merging //depot/project1/a.c#2
Diff chunks: 0 yours + 0 theirs + 0 both + 1 conflicting
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) [e]:
Enterを押すと、a.c のマージ結果を編集することになります。ここで "衝突マーカ" を探し、その衝突マーカおよび隣接する行を編集し、マージ結果として正しい内容にします。衝突マーカは、次に赤で示すように記述されます。:
>>>> ORIGINAL VERSION
==== THEIR VERSION
def
==== YOUR VERSION
abc
<<<<
編集を終了すると、p4 resolveは次の提案として、マージ結果のファイルを承諾する("am")ことを示します。
Accept(a) Edit(e) Diff(d) Merge (m) Skip(s) Help(?) [am]:
Enterを押すと、ここで編集し、マージしたファイルがクライアント・ワークスペースに保存されます。
最後に、マージ結果のファイルをサブミットします。
p4 submit
以上の操作は、単にディポにあるプロジェクト2のファイルを更新しただけでなく、プロジェクト1内のすべての変更がプロジェクト2へ反映されたという事実を記録したことになります。
しかし、逆向きはどうでしょうか? プロジェクト2内で行われた変更の中には、まだプロジェクト1へマージされていない変更があります。逆向きの反映操作は、1つの指定を除いて先ほどと同じです。その指定とは、次のようにp4 integrateに -r オプションを付けることです。
p4 integrate -r -b p1p2
これにより、プロジェクト2内のすべてのファイルがチェックされ、プロジェクト1にまだ反映していない変更が検出されます。もし何か見つかれば、同じ変更を行うために、該当するプロジェクト1のファイルが作業状態になります。このケースでは、プロジェクト2で削除されたファイルがプロジェクト1において削除目的で作業状態となり、プロジェクト2で追加されたファイルがプロジェクト1において "ブランチ/追加" 目的で作業状態となり、プロジェクト2で編集されたファイルがプロジェクト1において "反映" 目的で作業状態となります。削除されたファイルおよび追加されたファイルについては衝突解決の必要はありませんが、編集されたファイルについては次のコマンドを実行し、さらに、前述のようにマージ結果のファイルを編集します。:
p4 resolve
衝突解決が完了したら、最後にサブミットします。:
p4 submit
この時点で、プロジェクト1とプロジェクト2のコードラインは、完全に反映されました。もし、いずれの方向であっても、さらに反映操作を実行しようとすれば、"no file to integrate.(反映するファイルはありません.)" というメッセージが表示されます。
まとめますと、PERFORCEのブランチ操作は簡単です。branchコマンドを用いて再利用可能なブランチのマッピングを作成し、それからintegrateと submitを使って新しいコードラインを作り出します。コードライン間におけるマージ操作には、integrate、resolveおよび submitを実行します。
|