Subversion+svkでらくらく分散リポジトリ

第3回SVKとSubversion

2回に渡ってSubversionの使い方、Subversionとバグ管理システムとの連携について説明してきました。今回から、分散したSubversionのリポジトリを一元管理するSVKについて説明します。SVKはリポジトリの一元管理だけでなく、単体でも個人のバージョン管理の機能を提供しています。

SVKって何?

Subversionからいくつかの派生プロジェクトが生まれました。派生プロジェクトの1つに、2003年から開発が始まったSVKがあります。SVKは複数のバージョン管理システムのリポジトリを統一的に扱うためのツールです。リモートリポジトリとして、SubversionだけでなくCVSやPerforceなど、複数の種類のバージョン管理システムをサポートしているため、これらの違いを意識せずに操作できます。

SVKの一般的な作業フローは図1のようになります。まず、複数のサーバ上にあるリポジトリをローカルのSVKのリポジトリ(注: SVKではローカルのリポジトリのことを正式にはdepotと呼びますが、本稿ではリポジトリと呼びます)にミラーリングします(図1-①と図1-②⁠⁠。ローカルの作業コピー上で行なった変更は、ローカルのSVKのリポジトリにコミットされ、バージョン管理されます(図1-③と図1-④⁠⁠。作業がすべて終了した段階でローカルのリポジトリとリモートのサーバのリポジトリを同期して、変更分をサーバのリポジトリに反映します(図1-⑤と図1-⑥⁠⁠。Subversionなどがチームのバージョン管理で使われるのに対して、SVKは個人のバージョン管理ツールです。

図1 SVKの一般的な作業フロー
図1 SVKの一般的な作業フロー

例えば、今携わっているプロジェクトのSubversionのリポジトリhttp://example.com/svn/MyProject/があるとします。このプロジェクトで少し規模の大きな変更を行うことになりました。すべての修正を行ってテストを終えるまでに一週間かかります。バージョン管理は毎日おこなって、昨日と今日の修正分を確認し、場合によっては昨日の修正に戻す必要があります。変更を始めるとすべての修正が終わるまではプログラムは動作しないかもしれません。チームの他の人たちは別の作業を行っていて、プログラムが動かないと作業が中断することになります。

このような状況でSVKは威力を発揮します。SVKのリポジトリにSubversionのリポジトリのミラーを作成します。次にミラーからSVKのリポジトリ内にローカルブランチを作成し、このブランチで作業します。作業中は、ローカルで行った変更も差分や履歴を確認し、必要に応じて古いリビジョンに巻き戻しできます。すべての作業を終了し動作確認したら、Subversionのリポジトリに変更分をコミットしてチームの全員が最新のコードにアクセスできるようになります。

SubversionがCVSの基本的なバージョン管理の機能を改良したものであるのに対し、SVKは複数のソースコード管理を統一的に扱う手法を提供しています。下記は、SVKが提供している主な機能です。

  • オフライン操作:いくつかのバージョン管理システムはオフラインで操作できません。SVKではオフラインでも、リモートのリポジトリに対する読み込み専用の操作が可能です。
  • 分散操作:オフラインでもSVKへのリポジトリへの操作はすべて可能です(オンラインになったときに変更を同期できます⁠⁠。
  • マージのトラッキング:ブランチ間のマージは自動的にトラッキングします。そのため、マージするときに手動でリビジョン番号を指定するなどの煩わしさはありません。
  • パフォーマンスとスケーラビリティ:他のバージョン管理システムと比較してパフォーマンスやスケーラビリティに優れていると言われています。
  • 複数のバージョン管理システムのサポート:リモートのリポジトリとして、SubversionだけでなくCVSやPerforceなどとミラーリング、同期できます。
  • データの取り扱い:Subversionと同じ仕組みでテキストデータやバイナリデータを扱います。バイナリデータも効率的に差分をとることができます。

SVKのインストール

SVKのインストール方法を説明します。SVKの最新バージョンは、バージョン2.0.2です。Ubuntu LinuxではSVKのパッケージが提供されているので、次の方法でインストールしてください。

$ sudo aptitude install svk

MacOS Xでは、http://www.guiffy.com/download/download.htmlからユニバーサルバイナリのインストーラがダウンロードできます。SVKをインストールする前にあらかじめSubversionをインストールしておいてください。

Windows環境には、SVKのインストーラが提供されています。http://svk.elixus.org/view/SVKWin32からSVK 2.0.2のインストーラをダウンロードしてインストールします。インストールはグラフィカルにできますが、SVKの操作はすべてコマンドラインです。Windowsの「スタート」メニューにはSVKは登録されないので注意してください。

次のツールをインストールしておくと、マージの時に自動的に使用されます。TortoiseMergeはTortoiseSVN(Subversionクライアントのwindowsシェル拡張)をインストールするときに同時にインストールされます。

インストールが終ったらWindowsを再起動してコマンドプロンプトを立ち上げ、次のコマンドを入力してください。

> svk -v

次のメッセージが出力されれば成功です。

This is svk, version v2.0.2 (using Subversion bindings 1.4.4)

Subversionと違いSVKはまだGUIクライアントがないなど、一般の開発者には敷居が高いかもしれません。コマンドラインの操作も慣れればGUIクライアント以上の操作性を発揮することもあります。これを機会にコマンドラインの操作に親しんでみてください。

SVKを使ってみよう

まずは、SVKを使ってみましょう。操作はすべてWindowsで行なっていますが、MacOSXやLinuxではパスのセパレータが違うだけで、基本操作は全く同じです。今回の作業はCドライブの下にtmpディレクトリを作成して、そのディレクトリで行ないます。

リポジトリの準備

最初に、次のコマンドを入力して、SVK用のリポジトリを作成します。ホームディレクトリにリポジトリ.svk/localを作成するか聞かれます。⁠y」をタイプしてからリターンキーを押してください。

> svk depotmap --init
Repository C:\Documents and Settings\Administrator\.svk\local does not exist, create? (y/n)y
>

コマンドの操作で分らないことがあれば、次のコマンドでヘルプを表示できます。ただし、英語ですが…(^_^);

> svk help

リポジトリの準備ができたので、次のコマンドを実行して、リポジトリをc:\tmp\myprojにチェックアウトします。ほとんどの操作方法は、Subversionとほぼ同じです。SVKのリポジトリ表記は「//」で始まります。

C:\> cd c:\tmp
C:\tmp> svk checkout // myproj
Syncing //(/) in C:\tmp\myproj to 0.
C:\tmp\>

ファイルの追加とコミット

次にファイル、ディレクトリの追加とコミットを行なってみます。エクスプローラからc:\tmp\myprojディレクトリにtestディレクトリを作成します。そのディレクトリにReadMe.txtを次の内容で作成します。

This is test repository.

次のコマンドでSVKのリポジトリに追加予告します。addコマンドでディレクトリを指定すると、そのディレクトリ配下のすべてのファイルが追加予告されるので注意してください。addコマンドで追加予告しますが、実際にSVKのリポジトリに変更が反映されるのはcommitコマンドを実行したときです。この仕組みはSubversionと同じです。

C:\tmp\myproj>svk add test
A   test
A   test\ReadMe.txt
C:\tmp\myproj>

リポジトリに追加後、次のコマンドを実行して、SVKのリポジトリに変更を反映(コミット)します。Windowsではメモ帳が立ち上がります。メモ帳の最初の行にコミットのログメッセージを入力図2して保存、終了します。何も入力せずに保存すると、キャンセル(Abort)するか、継続(Commit)するか、ログメッセージを編集するか聞かれます。その場合は「C」をタイプしてからリターンキーを押し、コミットしてください。

図2 メモ帳へのログ入力画面
図2 メモ帳へのログ入力画面
C:\tmp\myproj>svk commit
Waiting for editor...
Committed revision 1.
C:\tmp\myproj>

差分表示

c:\tmp\myproj\test\ReadMe.txtに変更を加えて差分表示してみます。まずは、ファイルを次のように変更します。

This is test repository.
Is it working?

次のコマンドを実行して、SVKのリポジトリと作業コピーの差分を表示します。

C:\tmp\myproj>svk diff test\ReadMe.txt
=== test\ReadMe.txt
==================================================================
--- test\ReadMe.txt     (revision 1)
+++ test\ReadMe.txt     (local)
@@ -1 +1,2 @@
 This is test repository.
+Is it working?

変更を確認して間違いがなければ、コミットします。

C:\tmp\myproj>svk commit
Waiting for editor...
Committed revision 2.
C:\tmp\myproj>

変更分がリビジョン番号2で保存されたことが分ります。次のコマンドを実行してリビジョン1と2の差分を表示します。

C:\tmp\myproj>svk diff -r 1:2 test\ReadMe.txt
=== test\ReadMe.txt
==================================================================
--- test\ReadMe.txt     (revision 1)
+++ test\ReadMe.txt     (revision 2)
@@ -1 +1,2 @@
 This is test repository.
+Is it working?
C:\tmp\myproj>

ここまでの操作で、Subversionのコマンドラインからの操作とほとんど同じであることが分ると思います。

SVKのコンセプト

SVKは、単独でバージョン管理の機能を提供できますが、本当に便利な使い方ができるのは、複数のSubversionや他のバージョン管理システムと連携したときです。ここでは、Subversionとの連携を例に説明します。

Subversionと連携するとき、大きく二つのレイヤーに分けられます図3⁠。通常のSubversionなどのリモートサーバのリポジトリとSVKが動作しているローカルのマシン上でのリポジトリです。Subversionのリポジトリにはhttpやhttps、svnプロトコルでアクセスします。図のSubversionのリポジトリにはtrunkとbranch-remoteの二つのディレクトリがあり、branch-remoteはtrunkをコピーして作られたものです。

図3 リポジトリの構成図
図3 リポジトリの構成図

SVKが動作するマシン上には、SVKのリポジトリがあります。SVKのリポジトリ内にSubversionのリポジトリがミラーリングされており、trunkとbranch-remoteが存在します。SVKのリポジトリの中でもSubversionのリポジトリと同様にbranch-remoteはtrunkからコピーされたという情報を保持しています。この情報は後述するマージの際に重要になります。また、ミラーリングのスピードを上げるためにも重要です。

SVKではミラーリングしているディレクトリを直接操作はしません。通常は、ローカルリポジトリにtrunkのブランチを作成します。ここでは、branch-localを作成しています。最後にローカルリポジトリから作業コピーをチェックアウトしてコードの編集を行います。ここでは、branch-localとbranch-remoteをチェックアウトしています。チェックアウトしたディレクトリがミラーリングしているディレクトリか、ローカルブランチのディレクトリかで、コミット時の動作が変わります。この二種類を区別するのは重要です。

リモートとの同期 (sync)

ミラーリングしたリポジトリは定期的にリモートとのサーバと同期する必要があります図4⁠。同期を実行しないと、チーム内の他の人の変更を見ることができません。そのため、同期は定期的に行うのが好ましいです。syncコマンドでは、ローカルリポジトリのリビジョンとリモートリポジトリのリビジョン間の差分を転送し、ローカルリポジトリにマージ、コミットします。図からもわかる通り、同期はリモートリポジトリとローカルリポジトリの間で行われます。作業コピーには影響しません。

図4 リモートリポジトリとのミラーリングの概念図
図4 リモートリポジトリとのミラーリングの概念図

作業コピーの更新(update)

更新処理は、ローカルリポジトリの内容を作業コピーに反映する作業です図5⁠。リモートリポジトリと同期を行った後に、その変更を作業コピーにも適用します。この作業も定期的に行う必要があります。作業コピーとローカルリポジトリとの差分が大きくなれば、衝突が発生する可能性が高くなります。衝突が発生すると、連載の第一回目に述べたように手動でマージする必要があります。updateコマンドとsyncコマンドは別の作業なので個別に実行する必要があります。面倒な場合は、次のコマンドを実行することでsyncとupdateを同時に行えます。

$ svk update -s
図5 作業コピーの更新の概念図
図5 作業コピーの更新の概念図

コミット (commit)

コミットの動作は、どのツリーにコミットするかによって動作が変わります図6⁠。ローカルブランチbranch-localへコミットする場合は、ローカルのリポジトリに反映されるだけです。一方、branch-remoteの作業コピー上でコミットすると、変更分はリモートリポジトリに直接コミットされます。次にリモートサーバとローカルリポジトリと同期が行われて、変更分がローカルリポジトリにコミットされます。つまり、ローカルリポジトリへのコミットはオフラインでもできますが、リモートリポジトリへのコミットはネットワークにつながった状態でしかできません。

図6 コミットの動作概念図
図6 コミットの動作概念図

スターマージ(smerge)

スターマージはSVKでもっとも複雑な処理で、SVKを特徴づける機能の一つです。通常Subversionでブランチ間のマージを行う場合、リビジョン番号を明示的に使用しなければいけません。特に、ブランチでtrunkと同期をとりながら機能追加を行うのは至難の業です。定期的にブランチとtrunkの同期を行わないと、衝突が発生する可能性があります。一方で、頻繁に同期すると、コミットログからどのリビジョン間でマージを行ったか調べる必要があり、煩雑です。SVKではマージしたリビジョンや、どのツリーとどのツリーをマージしたか、という情報を保持しています。smergeコマンドを実行すると図7⁠、SVKが以前のマージ情報やコピー情報をもとに適切にマージします。リビジョン番号を指定する必要はありません。マージが正常に終了するとリモートリポジトリにコミットされ、ローカルリポジトリとリモートリポジトリで同期がされます。

図7 スターマージの動作概念図
図7 スターマージの動作概念図

今回はSVKのインストールと基本的な仕組みを説明しました。次回は具体的な例をもとにsvkの使い方を説明します。

おすすめ記事

記事・ニュース一覧