mac で svn を利用する

コードを書いたり、ドキュメントを書いたりしています.

ひょんなことから、複数の mac を渡り歩くことになってしまったので、どうにかして手軽にコードとドキュメントを管理する方法を確立しておく必要が出てきてしまいました.

MobileMe の iDisk を使って...なんてことも試していたんですが、素のまま使うとファイルの同期と管理がめんどくさいので、svnを経由しながら iDisk を活用してみたいと思います.

そんなわけで、手始めに mac 上で svn を動かしてみることにします

bash の設定

carbon Emacs から、shell 利用する際の設定は、ホームディレクトリの".bashrc"が読み込まれる.
最初は存在していないので、適当にファイルを作って作成する

bash から ls を行うと、日本語のファイル名が文字化けしてしまうため、言語設定を行う.

export LANG=ja_JP.utf-8

プロンプトの設定を行っておかないと分かりづらいので設定を行う.

PS1="[\u@\h:\w]$ "

PS1は、通常のプロンプトをどのように出力するかを設定する変数で、次の特殊文字が使える

特殊文字 意味
\d 日付
\h ホスト名
\n 改行
\s シェルの名前
\t 時間
\u ユーザー名
\w ワークディレクト
\W ワークディレクトリのベース名
\# コマンド番号
\! ヒストリ番号
\$ 有効なUIDが0なら「#」、それ以外なら「$」
\nnn 8進数での文字コード
\\ バックスラッシュそのもの
\[ 非表示文字の開始
\] 非表示文字の終了

まぁ、"(ユーザ名)@(ホスト名):(パス)" の表記をしておけば問題ないと思う.

svn のインストール

Mac OS X(10.5.5)では、svn がデフォルトでインストールされている.

そんなわけで、特にインストールに頭を使う必要はない.

一応バージョンの確認

[user@host:~]$ svn --version
svn, version 1.4.4 (r25188)
   compiled Sep 23 2007, 22:32:34

Copyright (C) 2000-2006 CollabNet.
Subversion is open source software, see http://subversion.tigris.org/
This product includes software developed by CollabNet (http://www.Collab.Net/).

The following repository access (RA) modules are available:

* ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol.
  - handles 'http' scheme
  - handles 'https' scheme
* ra_svn : Module for accessing a repository using the svn network protocol.
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme

svnadmin も確認しておく

[user@host:~]$ svnadmin --version
svnadmin, version 1.4.4 (r25188)
   compiled Sep 23 2007, 22:32:34

Copyright (C) 2000-2006 CollabNet.
Subversion is open source software, see http://subversion.tigris.org/
This product includes software developed by CollabNet (http://www.Collab.Net/).

The following repository back-end (FS) modules are available:

* fs_fs : Module for working with a plain file (FSFS) repository.

テスト用リポジトリの作成

[user@host:~/Documents/svn_repos]$ mkdir sandbox
[user@host:~/Documents/svn_repos]$ svnadmin create ./sandbox

リポジトリの取得(チェックアウト)

[user@host:~/Documents/sandbox]$ svn co file://localhost/users/user/Documents/svn_repos/sandbox
Checked out revision 0.

ファイルの追加

チェックアウトしたディレクトリに適当にファイルの追加.

[user@host:~/Documents/sandbox]$ cd ./sandbox
[user@host:~/Documents/sandbox/sandbox]$ echo "svnテストファイル" > test.txt
[user@host:~/Documents/sandbox/sandbox]$ cat ./test.txt 
svnテストファイル

~/Documents/sandbox フォルダからチェックアウトを行ったので、実際に取得されたディレクトリが ~/Documents/sandbox/sandbox になってしまっているけれども、所詮テストなんで気にしないことにする.

test.txt は、単純にファイルの作成をしただけなので、まだリポジトリには登録されていない.
svn status で、リポジトリの状態確認が行えるので、ファイルが追加されて*いない*ことを確認しておく

[user@host:~/Documents/sandbox/sandbox]$ svn status
?      test.txt

そしあて、 svn add で、ファイルの追加

[user@host:~/Documents/sandbox/sandbox]$ svn add test.txt
A         test.txt

svn add を行っただけでは、まだリポジトリに反映されていないため、コミットを行っておく

[user@host:~/Documents/sandbox/sandbox]$ svn commit -m "Add file"
Adding         test.txt
Transmitting file data .
Committed revision 1.

"Add file" の部分はコメントなので、適当に入力すればよい.

再度、svn status を実行してみると、すでにコミット済みなので何も表示されないことが分かる

[user@host:~/Documents/sandbox/sandbox]$ svn status

ファイルの変更

~/Documents/sandbox/sandbox/test.txt を開いて、適当に編集しておく

これは、svnテストファイルです

ファイルの変更を行う

svn status で状態の確認を行ってみる.

[user@host:~/Documents/sandbox/sandbox]$ svn status
M      test.txt

変更を行ったので、"M"マークがついたことが分かる.

差分の確認

svn diff で差分の確認を行うことができる.

[user@host:~/Documents/sandbox/sandbox]$ svn diff
Index: test.txt
===================================================================
--- test.txt	(revision 1)
+++ test.txt	(working copy)
@@ -1 +1,3 @@
-svnテストファイル
+これは、svnテストファイルです
+
+ファイルの変更を行う

コミットをして、編集結果をリポジトリに反映しておく

[user@host:~/Documents/sandbox/sandbox]$ svn commit -m "編集後のコミット"
Sending        test.txt
Transmitting file data .
Committed revision 2.
[user@host:~/Documents/sandbox/sandbox]$ svn status

ディレクトリの追加

ディレクトリの追加も、ファイルと同じように svn add を利用すればよい

[user@host:~/Documents/sandbox/sandbox]$ mkdir subdir
[user@host:~/Documents/sandbox/sandbox]$ svn add subdir
A         subdir

"svn mkdir (ディレクトリパス)" で、ディレクトリ作成と同時に追加を行うこともできる.

次に、作成したディレクトリに適当なファイルを追加

[user@host:~/Documents/sandbox/sandbox]$ cd subdir/
[user@host:~/Documents/sandbox/sandbox/subdir]$ echo "サブディレクトリのファイル" > hogehoge.txt
[user@host:~/Documents/sandbox/sandbox/subdir]$ cd ..
[user@host:~/Documents/sandbox/sandbox]$ svn status
?      subdir/hogehoge.txt
A      subdir
[user@host:~/Documents/sandbox/sandbox]$ svn add ./subdir/hogehoge.txt 
A  (bin)  subdir/hogehoge.txt

なぜか、バイナリとして判断されてしまったらしいけど、今は気にしないことにしておく.

そして、コミットしてリポジトリに反映

[user@host:~/Documents/sandbox/sandbox]$ svn commit -m "サブディレクトリとファイルの追加"
Adding         subdir
Adding  (bin)  subdir/hogehoge.txt
Transmitting file data .
Committed revision 3.

リポジトリの取得(再)

ちゃんとこれまでの変更が反映されているか、確認を行っておく.

一旦、ローカルコピーは削除する.

[user@host:~/Documents]$ rm -rf ./sandbox

svn_repos から再取得を行う.

[user@host:~/Documents]$ svn co file://localhost/Users/user/Documents/svn_repos/sandbox
A    sandbox/subdir
A    sandbox/subdir/hogehoge.txt
A    sandbox/test.txt
Checked out revision 3.

ちゃんと取得することができました.

他の人の反映を取得する(アップデート)

異なるディレクトリ上で、擬似的に多人数の開発を行ってみる

[user@host:~/Documents]$ cd mirror/
[user@host:~/Documents/mirror]$ ls
[user@host:~/Documents/mirror]$ svn co file://localhost/Users/user/Documents/svn_repos/sandbox
A    sandbox/subdir
A    sandbox/subdir/hogehoge.txt
A    sandbox/test.txt
Checked out revision 3.

mirror 上で、ファイルの新規追加を行う.

[user@host:~/Documents/mirror/sandbox]$ echo "mirror さんが追加したファイル" > ./newfile.txt
[user@host:~/Documents/mirror/sandbox]$ svn status
?      newfile.txt
[user@host:~/Documents/mirror/sandbox]$ svn add newfile.txt 
A         newfile.txt
[user@host:~/Documents/mirror/sandbox]$ svn commit -m "ファイルの新規追加"
Adding         newfile.txt
Transmitting file data .
Committed revision 4.

先ほど取得した sandbox 上で、mirror の変更を取得してみる.

[user@host:~/Documents/mirror/sandbox]$ cd ../../sandbox/
[user@host:~/Documents/sandbox]$ svn status
[user@host:~/Documents/sandbox]$ svn update
A    newfile.txt
Updated to revision 4.

mime-type の設定

ファイルを追加したときに、 svn がファイルをバイナリファイルだと勝手に認識してしまうことがある.

この場合、diff がとれなくなってしまうため、mime-type を削除するか、再設定を行う必要がある.

まずは、mime-type の確認から.

[user@host:~/Documents/mirror/sandbox]$ svn propget svn:mime-type hoge.txt
application/octet-stream

propget をおこなって、何も表示されない場合には、mime-type が設定されていない.

次に、mime-type の削除

[user@host:~/Documents/mirror/sandbox]$ svn propdel svn:mime-type hoge.txt
property 'svn:mime-type' deleted from 'hoge.txt'.

最後に、再設定.

[user@host:~/Documents/mirror/sandbox]$ svn propset svn:mime-type text/plane hoge.tex
property 'svn:mime-type' set on 'hoge.txt'
[user@host:~/Documents/mirror/sandbox]$ svn propget svn:mime-type text/plane hoge.tex
text/plane

まとめ

今回、利用した svn のコマンドをまとめておく.

コマンド 意味
svnadmin create リポジトリの作成を行う svnadmin create ./sandbox
svn co リポジトリのチェックアウトを行う svn co file://localhost/Users/user/Documents/svn_repos/sandbox
svn status (ローカルコピーの)ステータス確認を行う svn status
svn add ファイル(フォルダ)の追加 svn add test.txt
svn commit (ローカルコピーの)コミットを行う svn commit -m "Add file"
svn diff ローカルコピーとリポジトリの比較結果を表示する svn diff
svn update ローカルコピーのアップデートを行う svn update
svn propget svnが設定しているプロパティの取得 svn propget svn:mime-type hoge.tex
svn propdel svnが設定しているプロパティの削除 svn propdel svn:mime-type hoge.txt
svn propset svnが設定しているプロパティの(再)設定 svn propset svn:mime-type text/plane hoge.tex

おまけ

ローカルコピー上には、svnの管理ファイルとなる、".svn"フォルダが作成される.

ファイルの受け渡しなんかの時には、結構うざいので管理ファイルが無い状態でリポジトリの取得を行うことができる.

[user@host:~/Documents]$ svn export file://localhost/Users/user/Documents/svn_repos/sandbox
A    sandbox
A    sandbox/newfile.txt
A    sandbox/subdir
A    sandbox/subdir/hogehoge.txt
A    sandbox/test.txt
Exported revision 4.

おまけ2

もっと詳しく、svnのコマンドを調べたくなったら、以下を当たると良いと思う

http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/index.html