subversion

とりあえず難しい説明は無しで活用例をどんどん記述していく。簡単なチュートリアル的な感じで書きました。

インストール(debianの場合)

apt-get install subversion。コミットした時にメールを飛ばすフックスクリプトなどが欲しい場合はsubversion-toolsに入っているので慣れてきたらどうぞ。

レポジトリの作成

svnadminコマンドを利用する。ここでは/data/svn以下に「test」というレポジトリを作成してみる。

% svnadmin create /data/svn/test

subversion(以下svnとも略す)のファイル格納形式多きく

  • bdb
  • fsfs

の二種類が存在する。「fsfs」の方が利用勝手がよく、最近のバージョンのsubversionではこちらがよく利用される。 もちろん両者には長所もあり短所もある。比較した文書は以下のurlから参照する事が出来る。

http://subversion.bluegate.org/doc/ch05.html#svn.reposadmin.basics.backends

現在、どのようなファイルシステムで保存されているかを確認したい場合は/path/to/repos/db/fs-typeを見てやれば良い。この例だとfsfsになっているのがわかる。

% cat /data/svn/test/db/fs-type
fsfs

もし、bdbでレポジトリを作成したいのであれば、svnadmin createの後に

--fs-type

というオプションを付ける事。ただしbdbはよく壊れるし、ディレクトリに対してのパーミッションを必要とするので使い勝手は必ずしもよくない。(ただしツールはそれなりにある)

checkoutしてみる

レポジトリの作成が完了したのでチェックアウトという作業を行い、実際に作業を行う「ワーキングコピー」というものを作成してみる。既に作成したコードなり何なりが大量に手元に存在する場合は「checkout」するよりも「import」を行った方が効率的な事もあるが、今回はまだ何も作成していないので、とりあえずチェックアウトしてみる事にする。

ワーキングコピーはどこでもいい、今回は「/data/www/test」へとチェックアウトしてみる事にする

% svn checkout file:///data/svn/test /data/www/test

この例だと既に/data/www/にcdしている場合は最後の「/data/www/test」という引数は不要である。特定のパスにチェックアウトする場合のみこの引数を指定する。指定しなければレポジトリの名前のディレクトリ(この場合はtest)がカレントディレクトリに作成される。/data/www/testをlsしてみると一見何も無いように見えるが「.svn」というディレクトリが作成され、その中にワーキングコピーとして必要なファイル一式が格納されている。findしてみるとわかりやすい。

% find /data/www/test
/data/www/test
/data/www/test/.svn
/data/www/test/.svn/empty-file
/data/www/test/.svn/entries
/data/www/test/.svn/format
/data/www/test/.svn/prop-base
/data/www/test/.svn/props
/data/www/test/.svn/README.txt
/data/www/test/.svn/text-base
/data/www/test/.svn/tmp
/data/www/test/.svn/tmp/prop-base
/data/www/test/.svn/tmp/props
/data/www/test/.svn/tmp/text-base
/data/www/test/.svn/tmp/wcprops
/data/www/test/.svn/wcprops

今後はワーキングコピーのディレクトリである/data/www/testにcdし、ここで作業を進めていく事とする。

3つのディレクトリ

subversionを利用するにあたって通常以下の3つのディレクトリを作成する事が慣例になっている。

  • trunk
  • branches
  • tags

これらは必須では無いが、少なくともtrunk/以下で作業をする事を推奨する。実はtrunkさえも必要無いのだが、こういったディレクトリ構成にしておかないと後々タグやブランチを切りたいと思った時に上手くやる事が出来ないからである。 もちろん、タグやブランチ等を必要としない細々としたような(例えば設定ファイルのような)ファイルの管理を行いたいといった場合はこれらのディレクトリは不要である。その点においてはsubversionは自由度が高い反面管理方法はユーザに一任されるという事にもなる。

今回は慣例に基づき、これら3つのディレクトリを作成し、それをレポジトリに反映させる事を行う(実際にはこれらのディレクトリを先に作成しておき、importする事から始める事も多い。まぁ好みで…)

ディレクトリの作成

ワーキングコピーにcdし、trunk, tags, branchesという3つのディレクトリを作成すれば良い

% mkdir trunk tags branches
% ls -a
./  ../  .svn/  branches/  tags/  trunk/

コミットの準備

現在の状態は、ただディレクトリを作成しただけなので、未だレポジトリには反映されていない。ワーキングコピーの変更をレポジトリに反映するためにはコミットという作業を行う必要がある。

ただし、コミットするためには前準備としてaddという作業を行いコミットする準備を整えないといけない。

試しに現在のディレクトリで「svn status」と入力してみる

% svn status
?      trunk
?      branches
?      tags

このように、作成されたディレクトリ対しては「?」というマークが付いている。これは簡単に言うと、ワーキングコピー内に新たに追加されたファイルまたはディレクトリを表していると思えば良い。

これらのディレクトリをワーキングコピーに対してコミットさせるように認識させるには以下のように「svn add」というコマンドを用いて追加の準備を行う

% svn add trunk branches tags
A         trunk
A         branches
A         tags

もちろん、ワイルドカードを用いて一度に追加してもいいが、ここでは一つずつディレクトリを指定してみた。

すると今まで「?」として示されていたディレクトリに対して「A」というマークに変わっている。これはこの状態で「svn status」としても同様に確認できる。

% svn status
A      trunk
A      branches
A      tags

この「A」という状態は「コミットできる準備が出来るようにワーキングコピーにファイル(ディレクトリ)を追加」した事を示している。次の作業で実際にコミットする作業を行ってみる。

レポジトリへのコミット

「svn status」で「A」のマークが付いているものはコミットされる準備が整っているので、あとはこのワーキングコピーへの変更をレポジトリに「コミット」してやるだけである。

コミットする際には「コメント」を記述でき、その為のエディタは環境変数で指定できるのだが、ここでは「-m」というオプションを利用してコマンドラインにコメントを埋めこんでみる。

% svn commit -m 'add initial dir'
Adding         branches
Adding         tags
Adding         trunk

Committed revision 1.

これでディレクトリの追加は完了した。本当にディレクトリが正しく追加されたかどうかは「svn ls」コマンドで確認できる。

% svn ls file:///data/svn/test/
branches/
tags/
trunk/

「svn」コマンドに関してはレポジトリの指定は「URI」で行う必要がある事に注意したい。

なお今回はチェックアウトしたレポジトリに対してadd → commitという作業を踏んだが、「svn mkdir」というコマンドを利用しても良い(今回は利用法は割愛する)し、かなり前に書いたように「import」でつっこんでも良い。

trunkでの開発

さて、「branches」、「tags」、「trunk」という3つのディレクトリのセットアップが終了したので、いよいよ開発を進めていく事にする。開発を進めるにあたっては「trunk」というディレクトリ内でやるのが慣習となっているのでtrunkにcdする。

% ls
branches/  tags/  trunk/
% cd trunk
% ls -a
./  ../  .svn/

このようにtrunk内には.svnというドットディレクトリが作成されているはずだ。より詳細なレポジトリの情報を得たい場合はsvn infoとする。これによりsvnは.svnディレクトリより必要な情報を取り出し、整形して返してくれる。

% svn info
Path: .
URL: file:///data/svn/test/trunk
Repository Root: file:///data/svn/test
Revision: 1
Node Kind: directory
Schedule: normal
Last Changed Author: USER
Last Changed Rev: 1
Last Changed Date: 2006-08-25 17:48:54 +0900 (Fri, 25 Aug 2006)

ファイルの作成とステータスの確認、追加

subversionで管理できるのはテキストファイルだけではないが、基本的にこういったバージョン管理システムはテキストを管理するのに特化した作りになっている。よってここでは適当なテキストファイルを作成し、それをリポジトリに追加してみる事にする。

ここではmemo.txtというテキストファイルを作成し、以下のように記述してみることにした。

2006-08-25

	* 天気: 今日は比較的天気の良い日だ。

中途半端にchangelogっぽいのはともあれ、まぁこんな感じでテキストを作成したとする。

% cat memo.txt
2006-08-25

        * 天気: 今日は比較的天気の良い日だ。

ここでsvn statusと入力してみる事にする。

% svn status
?      memo.txt

ファイルの場合もディレクトリと同様に自身のレポジトリに無いファイルが追加された場合はこのように「?」マークが付く。 これを追加する方法は既に行ったように「svn add」した後「svn commit」する事である。

% svn add memo.txt
A         memo.txt
% svn commit -m 'initial' memo.txt
Adding         memo.txt
Transmitting file data .
Committed revision 2.

これによりmemo.txtがレポジトリの管理下に収められた。

ファイルおよびディレクトリを新規に追加する方法は常にこの方法になる。以降はファイルを修正した時の挙動に関して記述する。

ファイルの修正および変更点の確認

追加したファイルに修正をかけてみる。

2006-08-26

	* 天気: 今日は大雨だった。

2006-08-25

	* 天気: 今日は比較的天気の良い日だ。

レポジトリ管理下に置かれているファイルに対し修正をかけたので「svn status」を行うと以下のように「M(Modified)」のマークが付いている事がわかる。

% svn status
M      memo.txt

どのような変更が行われたのかは「svn diff」を用いればわかる

% svn diff
Index: memo.txt
===================================================================
--- memo.txt    (revision 2)
+++ memo.txt    (working copy)
@@ -1,3 +1,7 @@
+2006-08-26
+
+       * 天気: 今日は大雨だった。
+
 2006-08-25

        * 天気: 今日は比較的天気の良い日だ。

このように追加された部分は「+」で表示される。

この変更をレポジトリに適用するには「svn commit」を行う。

% svn commit -m 'add entry' memo.txt
Sending        memo.txt
Transmitting file data .
Committed revision 3.

このように、新規に追加する場合は「add → commit」、修正する場合はそのまま「commit」とする。ワーキングコピー内のファイルステータスはいつでも「svn status」で確認できる。

古いリビジョンのファイルを取り出す

一番簡単なのは「svn cat」にリビジョン指定してやる事である。

% svn cat -r 2 memo.txt
2006-08-25

        * 天気: 今日は比較的天気の良い日だ。

これをリダイレクト等して上書きしたものをコミットすれば古いリビジョンに戻せる。また「update」と「merge」を利用する方法もあるがここでは割愛する。

コミットログを見る

「svn log」を利用すればコミットされた時のログを見る事が出来る

% svn log memo.txt
------------------------------------------------------------------------
r3 | USER | 2006-08-31 16:47:48 +0900 (Thu, 31 Aug 2006) | 1 line

add entry
------------------------------------------------------------------------
r2 | USER | 2006-08-31 14:21:56 +0900 (Thu, 31 Aug 2006) | 1 line

initial
------------------------------------------------------------------------

このように変更があったリビジョンとその時のユーザやタイムスタンプ、コメント等を見る事が出来る。「r2」とか「r3」とか書いてあるものがリビジョンで、リビジョン間のdiffを見る場合は以下のように指定してやる

% svn diff -r2:3 memo.txt
Index: memo.txt
===================================================================
--- memo.txt    (revision 2)
+++ memo.txt    (revision 3)
@@ -1,3 +1,7 @@
+2006-08-26
+
+       * 天気: 今日は大雨だった。
+
 2006-08-25

        * 天気: 今日は比較的天気の良い日だ。

タグを打つ

タグとはある一定のバージョンのスナップショットである。ここではタグの打ち方、および取り出し方を説明する。

レポジトリの状態

まず、タグを打つ前のレポジトリの状態を確認しておく。 現在はmemo.txtのみ入っている状態なのでもう少しだけ複雑にしておく事にする。

% echo mogemogemoge > moge.txt
% mkdir test
% echo testtesttest > test/test.txt

% svn status
?      test
?      moge.txt

% svn add test moge.txt
A         test
A         test/test.txt
A         moge.txt

% svn commit -m 'test add'
Adding         trunk/moge.txt
Adding         trunk/test
Adding         trunk/test/test.txt
Transmitting file data ..
Committed revision 4.

% ls
memo.txt  moge.txt  test/

とまぁこんな感じの状態を保存しておく事にする。

タグを打ってみる

タグを打つには「svn copy」というコマンドを利用する。サブコマンド名からわかるように「タグを打つ」というのはその状態のレポジトリの内容を「コピー」するというのとほぼ等価である。

「svn copy」はレポジトリのパスに対して直接行う

% svn copy -m '1.1' file:///data/svn/test/trunk file:///data/svn/test/tags/1.1

Committed revision 5.

「svn ls」でリポジトリ内にタギングされた構成を見る事が出来る

% svn ls file:///data/svn/test/tags
1.1/

これで現在のtrunkの状態がtags/1.1として保存された

タグを打った後のレポジトリに変更を加えてみる

タグ1.1とtrunkの内容の差分を得る為に再度trunkに変更を加えてみる事にする。

% echo mogemogemoge > moge2.txt
% echo testtesttest > test/test2.txt

% svn status
?      moge2.txt
?      test/test2.txt

% svn add moge2.txt test/test2.txt
A         moge2.txt
A         test/test2.txt

% svn commit -m 'change trunk'
Adding         trunk/moge2.txt
Adding         trunk/test/test2.txt
Transmitting file data ..
Committed revision 6.

これでtrunkに変更がかかった。

チェックアウトしてみる

ここでtrunk内のファイルとtags/1.1に入っているレポジトリを全く別のパスにチェックアウトして比較してみる。

ここではとりあえず/tmpを利用してみる。

% cd /tmp

まずtrunkをチェックアウトしてみる

% svn checkout file:///data/svn/test/trunk
A    trunk/test
A    trunk/test/test2.txt
A    trunk/test/test.txt
A    trunk/moge.txt
A    trunk/moge2.txt
A    trunk/memo.txt
Checked out revision 6.

このように先程加えられた「moge2.txt」、「test/test2.txt」もチェックアウトされた事を確認する。必要なら中身をcat。

同様に先程「tags/1.1」として保存したものをチェックアウトしてみる。

% svn checkout file:///data/svn/test/tags/1.1
A    1.1/test
A    1.1/test/test.txt
A    1.1/moge.txt
A    1.1/memo.txt
Checked out revision 6.

ブランチ

trunkの状態を残しておきつつ平行して別のバージョンを作成したいような時がある。その場合「ブランチ」を使う。

subversionにおいてはブランチもタグも同じような扱いなので「svn copy」を利用する。

ブランチはbranchesに保存するのが普通。ここでは「branches/1.2」としてsvn copyしてみる。

% svn copy -m 'branch 1.2' file:///data/svn/test/trunk file:///data/svn/test/branches/1.2

Committed revision 7.

% svn ls file:///data/svn/test/branches
1.2/

ブランチにおける作業

普通にチェックアウトして、そこで作業していく

% svn co file:///data/svn/test/branches/1.2
A    1.2/test
A    1.2/test/test2.txt
A    1.2/test/test.txt
A    1.2/moge.txt
A    1.2/moge2.txt
A    1.2/memo.txt
Checked out revision 7.

% cd 1.2

とりあえず適当に変更をかけてみる

% svn status
?      moge3.txt
M      memo.txt

% svn diff
Index: memo.txt
===================================================================
--- memo.txt    (revision 7)
+++ memo.txt    (working copy)
@@ -1,3 +1,7 @@
+2006-08-27
+
+       * 天気: 今日は一日中曇りだったが、涼しい日だった。
+
 2006-08-26

        * 天気: 今日は大雨だった。

% svn add moge3.txt
A         moge3.txt

% svn commit -m 'modified'
Sending        memo.txt
Adding         moge3.txt
Transmitting file data .
Committed revision 8.

これでブランチへの変更は行われたわけだが、trunkには影響しない。

trunkへの反映

まずbranchを作った時のリビジョンを調べる。これはsvn log等すればわかる(branch内で–stop-on-copyをつけるとよりわかりやすい)

% svn log file:///data/svn/test/branches/1.2

ここではrev.7でブランチを作ったので、これを元に「マージ」という作業を行う。

とりあえずtrunkにcdする。

ここで「svn merge」する

% svn merge -r 7:HEAD file:///data/svn/test/branches/1.2
A    moge3.txt
U    memo.txt

最終的にcommitをかければtrunkの方にも反映される。

trunkからbranchへの反映

trunkからブランチした場所で開発をすすめていたのだけれどtrunkに変更がかかったものをさらにとりこみたいという事もあるだろう。たとえば以下のように

% diff -u  branches/test/test.txt trunk/test.txt
--- branches/test/test.txt      2009-07-23 16:57:14.000000000 +0900
+++ trunk/test.txt      2009-07-23 16:58:17.000000000 +0900
@@ -3,3 +3,4 @@
 mogemoge
 ---------
 mogemoge
+this is trunk text

trunk/test.txtに変更がかかっているのだがbranches/test/test.txtには変更がかかっていない。これを取り込みたいとする。これはtrunkに反映させたのと全く同じ事をbranchesの中でやれば良い。

r15でブランチを切ったとするならば以下のようにする

% svn merge -r 15:HEAD file:///data/svn/test/trunk/ 
--- Merging r16 through r17 into '.':
U    test.txt

後はコミットするだけ

ダンプとかリストアとかする

(スタブ)

外部リソースへのリンク

svn.txt · 最終更新: 2012/04/13 18:24 by admin
www.chimeric.de Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0