CVS/Subversionを使ったバージョン管理(後編:SVNを使ったバージョン管理)


 SubversionCVS使CVSSubversion

 SubversionCVSCVSSubversion

Subversion


 SubversionUNIX/LinuxWindowsMac OS XSubversionSubversionAIXHP-UXSolarisUNIXWindowsMac OS XLinuxBSDLinuxFreeBSDOpenBSDCygwin

 WindowsSubversionSubversionCollabNetSubversionCUIsvn使CollabNet Subversion Command Line Client

 Mac OS XopenCollabNetFinkMacPorts

 WindowsTortoiseSVNGUISubversion

Subversion


 SubversionSubversion1
プロトコル 説明
file ローカルのファイルシステムにアクセスする場合に使用する
http、https サーバーとしてApache httpdを使用する
svn サーバーとしてSubversion付属のsvnserveを使用する
svn+ssh サーバーとしてSubversion付属のsvnserveを使用し、さらにSSHを利用して暗号化された通信経路を使用する
表1 Subversionで利用できるプロトコル

 もし既存のSubversionリポジトリに接続する場合は、リポジトリ側が推奨するプロトコルを使用すればよい。たとえばSourceForge.JPのSubversionリポジトリでは、httpおよびsvn+sshが利用できる(httpによるアクセスはチェックアウトのみ可能)。

 一方、自分でSubversionサーバーを用意する場合は、どのプロトコルを利用するか事前に検討しておく必要がある。使用するプロトコルによってサーバーの設定方法などは異なるので、注意が必要だ。

 サーバーの設定が完了したら、サーバーのファイルシステム内にリポジトリを作成する。リポジトリの作成には、Subversionに付属するsvnadminコマンドを使用する。まず、リポジトリのルートディレクトリとして使用するディレクトリを作成し、続いて「svnadmin create」コマンドを実行する。

$ svnadmin create <リポジトリのルートディレクトリ>

 これにより、リポジトリのルートディレクトリにデータベースや設定ファイル一式が作成され、リポジトリが利用できるようになる。

Subversionサーバーの設定

 Subversionでは、利用するプロトコルにより、利用するサーバーが異なる。最もセットアップが手軽なのが、svn+sshプロトコルを利用する場合だ。この場合、SSH経由で自動的にsvnserverが起動されるため、svnserveプロセスを常時立ち上げておく必要はない。また、認証はSSHによって行われるため、「SSHでアクセス可能なユーザー」=「リポジトリにアクセス可能なユーザー」となり、ユーザー管理が行いやすい。

 一方、WindowsをSubversionサーバーとして利用する場合や、SSHを使用したくない、といった場合はsvnプロトコル、もしくはhttp/httpsを利用することになる。svnプロトコルはセットアップが容易で、設定ファイルを用意してサーバーとなるsvnserveプロセスを動かしておくだけで利用可能になる。ただし、通信内容の暗号化や、通信ログの保存などには対応していない。それに対し、httpやhttpsは別途Apacheおよびmod_dav_svnモジュールのセットアップが必要となる。これらについては本記事内では触れないので、別途Subversion付属のマニュアルなどを参照してほしい。

リポジトリにファイルをインポートする

 リポジトリに新たにファイルを登録する(インポートする)には、「svn import」コマンドを使用する。

svn import <対象ファイル/ディレクトリ> <プロトコル>://<ユーザー名>@<サーバー>/<リポジトリのルートディレクトリ>/<登録先ディレクトリ>

 たとえば、次のような条件でインポートを行うとしよう。

  • ユーザー名:「john」
  • Subversionサーバー:「svn.sourceforge.jp/svnroot/testproj/」
  • 登録先ディレクトリ:「trunk/foobar」
  • 登録したいファイルやディレクトリが格納されているディレクトリ:「./foobar/」

 この場合、下記のように実行すればよい。

$ svn import foobar svn+ssh://john@svn.sourceforge.jp/svnroot/testproj/trunk/foobar
Subversionリポジトリの推奨構造

 Subversionでリポジトリを管理する場合、リポジトリのルートディレクトリ、もしくはそのサブディレクトリ以下に「trunk/」「tags/」「branches/」という3つのディレクトリを作成するのが慣例となっている(図1図2)。trunk/は開発の本流となるファイル(HEADなどとも呼ばれる)を格納するディレクトリ、tags/は特定のツリーのスナップショットを保存しておくディレクトリだ。また、branches/はメインのソースツリーとは異なる更新を加えたい(ブランチを作成する)場合に使用するディレクトリとなる。通常、リポジトリに新しくディレクトリ(およびファイル)を登録する際は、trunk/ディレクトリ以下にサブディレクトリを作成してファイルを登録することが多い。

図1 図2
図1 リポジトリ構造の例1:ルートディレクトリ以下にtrunk、tags、branchesディレクトリを作成 図2 リポジトリ構造の例2:ルートディレクトリ以下にプロジェクトごとのディレクトリを作成し、それぞれにtrunk、tags、branchesディレクトリを作成

リポジトリからファイルを取り出す

 リポジトリに保存されているファイルをローカルに取り出す(チェックアウトする)には、「svn co」コマンドを使用する。「co」は「checkout」の略で、「svn checkout」と実行しても同じ結果が得られる。svn coコマンドの書式は次のとおりだ。

svn co svn+ssh://<ユーザー名>@<サーバー名>/<取得したいディレクトリのパス>

 たとえば、次の例は「john」というユーザーで「svn.sourceforge.jp」というサーバーにある「/svnroot/testproj/foobar」というディレクトリ以下のファイルを、カレントディレクトリ以下にチェックアウトするものだ。これを実行すると、カレントディレクトリに「foobar」というディレクトリが作成され、「foobar/」以下に取得したファイルが保存される。

$ svn co svn+ssh://john@svn.sourceforge.jp/svnroot/testproj/foobar
Enter passphrase for key '/home/john/.ssh/id_rsa': ←sshのパスフレーズを入力
A    foobar/hello.c
A    foobar/docu1.txt
Checked out revision 2.
SourceForge.JPにおけるSubversionの利用

 SourceForge.JPSubversionSourceForge.JPSubversionsvn.souceforge.jp/svnroot/<UNIX>

 sampleprojjohn
$ svn co svn+ssh://john@svn.sourceforge.jp/svnroot/sampleproj

 SourceForge.JPhttpsampleproj
svn co http://<サーバー名>/<サーバー名>/<取得したいディレクトリのパス>

 SourceForge.JPSubversionsvn+shh

加えた変更をリポジトリに保存する


 svn ci使cicommitsvn commit
svn ci <コミットするディレクトリ>

 SVN_EDITORVISUALEDITOR

 
$ svn ci
svn: Commit failed (details follow):
svn: Can't create directory '/svnroot/testproj/db/transactions/2-1.txn': Permission denied
svn: Your commit message was left in a temporary file:
svn:    '/Users/john/temp/foobar/svn-commit.tmp'


 svn update使
svn update <コミットするディレクトリ>

 cisvn update


 

 echo.plsvn-commit.tmp
$ svn ci
Sending        echo.pl
Transmitting file data .svn: Commit failed (details follow):
svn: Out of date: '/echoes/echo.pl' in transaction '2-1'
svn: Your commit message was left in a temporary file:
svn:    '/home/john/Dev/echoes/svn-commit.tmp'

 svn update

 echo.pl
$ svn update
Conflict discovered in 'echo.pl'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (h) help for more options:

 dfEnterpEnter<<<<<<< .mine==============>>>>>>> .r<>
my $form_data = {
  'next_url' => '/home.pl',
<<<<<<< .mine
  'email' => '',
  'password' => '',
=======
  'email' => 'hogehoge@foobar.com',
  'password' => 'qwerty',
>>>>>>> .r2
  'stickey' => '1',
};

 update<>.mine<>.r<><>.r<>3
ファイル名 説明
<ファイル名>.mine 自分が変更を加えてコミットを行おうとしたファイル
<ファイル名>.r<変更前リビジョン> 変更を加える前のファイル
<ファイル名>.r<変更後リビジョン> リポジトリ内にある最新リビジョンのファイル
表2 競合発生時に作成されるファイル

 <>.mine<><>.r<><>

 svn resolved <><>.mine<>.r<><>.r<>


 svn add使
svn add <追加するファイル>

 svn addsvn addsvn ci


 svn del使svn deletesvn removesvn rm
svn del <削除するファイル>

 svn delsvn add

/


 svn move使svn mvsvn renamesvn ren
svn mv <変更前> <変更後>

 /svn del


 svn cp使svn copy
svn cp <コピー元ファイル/ディレクトリ> <コピー先>

 foo../branches/foo01
$ svn cp foo ../branches/foo01

/


 CVSSubversionsvn cp使tags/

 trunk/foobar/
$ svn cp svn+ssh://john@svn.sourceforge.jp/svnroot/testproj/trunk/foobar svn+ssh://john@svn.sourceforge.jp/svnroot/testproj/tags/foobar-1.1

 foobar-1.1tags/

 branches/


 svnsvnsvn help使svn helpsvnsvn help <>svn help

 svn
svn status ワーキングコピーに加えた変更状況を確認する
svn diff 自分がワーキングコピーに加えた変更点のdiffを表示する
svn diff -r <比較元リビジョン>:<比較先リビジョン> <ファイル名> 指定したファイルの<比較元リビジョン>と<比較先リビジョン>のdiffを表示する
svn revert <ファイル名> ワーキングコピーの指定したファイルに自分が加えた変更をすべて削除する
svn log リポジトリの変更履歴を表示する
svn cat -r <リビジョン> :<ファイル名> 指定したファイルの指定したリビジョンでの内容を表示する
svn list :<リポジトリ> 指定したリポジトリに含まれるファイル一覧を表示
表3 リポジトリの状態を確認するコマンド