前回の記事ではSVKの基本的な操作方法を説明しました。最終回の今回はSubversionのリポジトリと連携しながら、SVKの使い方を説明します。
リモートのSubversionのリポジトリとして、本連載第2回目で説明した方法でSubversionのリポジトリを作成します。リポジトリを作成しただけではファイルがない状態です。今回はテスト用のデータを用意しました。ファイルをダウンロードしてc:\tmp\ディレクトリに展開してください。展開後、次のコマンドを実行して、Subversionのプロジェクトにインポートします。
次にtrunkからテスト用のブランチを作成します。
これまでの操作で図1のようなディレクトリ構造になります。
以上で準備ができました。これから、SVKのリモートリポジトリ管理を行ないます。今回のミッションでは、trunkでファイルの変更を行い、コミットします。次に、trunkの変更分をbranchにマージします。
リモートリポジトリをミラーリング
SVKで管理するときは、まず、リモートリポジトリをSVKのローカルにミラーリングします。次のようなコマンドの書式になります。
それでは、ミラーリングを行ないます。次のコマンドを実行してください。
ここでは、//mirrorと言うパスにミラーリングしています。ここでは、SVKのファイルの保管場所のことをローカルリポジトリ、SVKリポジトリ内の各ディレクトリのことをパスと呼びます。複数のリモートリポジトリを管理する場合は、「//mirror/プロジェクト名」のようにパスを指定すると分りやすいです。
次のコマンドを実行することで、ミラーリングしているパスを確認できます。
ミラーしたものは、現在のリモートリポジトリのスナップショットです。チームで開発している場合、あなたの作業中にもファイルを更新しているかもしれません。定期的に、ミラーリングしているローカルリポジトリをリモートリポジトリと同期する必要があります。次のコマンドを実行して、リモートリポジトリと同期してください。
複数のリモートリポジトリを管理している場合は、次のコマンドを実行することで、すべてのリモートリポジトリと同期できます。
ローカルブランチがあなたの作業領域
SVKではミラーリングしているパスに対して直接編集しません。代わりに、ローカルリポジトリ内でローカルのブランチを作成します。次のコマンドを実行して、//mirror/trunkを//workにコピー(ブランチを作成)します。ミラーしているパスをチェックアウトした場合、コミットするとSubversionのリポジトリに直接コミットされてしまいます。ミラーしているパスをチェックアウトしないように注意してください。
作業用ブランチが作成できたので、作業コピーとしてファイルをチェックアウトします。次のコマンドを実行して、//workをc:\tmp\MyProjectにチェックアウトします。
現在のリポジトリの構造は図2のようになっています。
作業領域を最新に
「svk sync」を実行することでミラーリングしているパスをリモートリポジトリと同期して最新の状態にできます。しかし、ローカルブランチは古いリビジョンの状態のままです。ローカルブランチを最新の状態にするためには、マージ(smerge)します。
まず、Subversionのクライアントを使ってリポジトリに変更を加えておきます。今回はテスト用に、trunkのdocsディレクトリを削除して、次のようにREADME.txtの最初の方に文書を追加しています。
最初に次のコマンドを実行して、ミラーリングしているリポジトリを最新の状態にします。
次に、ローカルブランチ//workにマージします。実際にローカルブランチにマージする前に、次のコマンドを実行してコンフリクトがないかチェックします。
この結果から、衝突はなく問題なくマージできることがわかります。次のコマンドを実行して、マージします。「-l」オプションを指定すると、コミットメッセージとして、Subversionのコミットログが自動的に使用されます。これは、ローカルで起きた変更とリモートで起きた変更が区別できるので、履歴を確認するときに役立ちます。
これで、SVKのローカルブランチが最新の状態になりました。最後に、次のコマンドを実行して作業コピーを最新の状態にします。
衝突が起きたとき
開発中にはなるべく衝突が起きないようにすることが大事ですが、実験的な修正を行なっているときやブランチでの作業中は衝突が発生することがあります。次に、衝突が起きたときの動作を見てみましょう。
衝突が起きるように、まず、Subversionのリポジトリのファイルhttp://localhost/svn/MyProject/trunk/README.txtを次のように編集してコミットします。
ローカルの作業コピーC:\tmp\MyProject\README.txtを次のように変更します。
C:\tmp\MyProject\README.txtを変更後、次のコマンドを実行して、ローカルリポジトリにコミットします。
これで衝突が起きる状態になりました。まず、リモートリポジトリとミラーリングしているリポジトリを同期します。
同期が完了後、マージを行ないます。
コマンドを実行すると、コミットログの入力を求められるので、最初の行に「conflict test」と入力します。しばらくすると、次のメッセージが表示されます。
「d」を入力すると、次のような差分が表示されます。
自分の変更を適用する場合は「y」,リモートリポジトリの変更を適用する場合は「t」を入力します。マージする場合は「m」を入力します。今回はファイルを直接編集するので、「e」を入力します。notepadが立ち上がり、ファイルの内容が次のように表示されます。 表示の形式は本連載1回目の衝突ファイルの表示形式と同じです。
このファイルを編集して保存、終了すると次のメッセージが表示されます。「a」を入力するとこの変更が適応されます。「e」を押すと再編集できます。「d」を押すとオリジナルとの差分を表示します。「s」を押すと変更が破棄されます。ここでは「a」を押して変更をコミットします。
修正が終わると、ローカルリポジトリのローカルブランチに変更がコミットされます。マージが終るわと、次のコマンドを実行してSVKの作業コピーに更新を反映します。
マージは複雑なように見えます。ブランチへのマージではSubversionの場合、前回マージしたときのリビジョンと現在マージしようとしているリビジョンの番号を調べてマージする必要があります。SVKではマージするリビジョンはすべて自動で処理されるため、Subversionより簡単に処理できます。マージ時には、二つのリビジョン間の単純な差分ではなく、そのリビジョン間で起きたすべての差分情報をもとにマージするため、Subversionのマージより安全です。
変更をリポートリポジトリに反映
現状ではローカルリポジトリに加えた変更は、Subversionのリモートリポジトリには反映されていません。次にリモートリポジトリに変更分をコミットする作業を行います。次のコマンドを実行して、リモートリポジトリに反映します。smergeコマンドは、マージ先がミラーリングしているパスの場合、マージ処理を行なった後にSubversionのリポジトリにコミットします。その後、Subversionのリモートリポジトリとミラーリングしているパスを同期します。
図3は、TracのリポジトリブラウザからSubversionのリポジトリを参照しています。マージした結果が反映されているのが分かるでしょうか?
//mirror/branches/remoteに変更分をマージするには、次のコマンドを実行します。これは、ブランチが作成されたときのリビジョン情報とworkに対して加えられた変更を元に、必要な変更分だけをマージします。
Tracのリポジトリブラウザでbranchの内容を確認してみてください。branchにも変更が適用されているのが分ると思います。SVKを使って定期的にtrunkからbranchにマージを行なうことで、trunkの変更をbranchに簡単に適用できます。Subversionでこの作業を行ったことがある人は分かると思いますが、これはとても煩雑で難しい作業です。SVKでは、この作業の大半を自動で行なうので、かなりの作業が軽減されます。
おわりに
2回にわたってSVKの機能について説明してきました。SVKには本連載では説明できなかった多くの機能があります。まだ一部のギークにしか認知されていない、コマンドラインのクライアントしかないなど、一般の開発者には敷居が高いかもしれません。しかし、Subversionのマージ機能に不満を持っている方や、trunkとbranch両方のツリーで作業をされている方は一度検討してみるといいかもしれません。