cvsにいい加減むかついていたのでsvnに移行することにした。~
ここはそのsvnのコマンドのメモや、はまったところなどを記録しているメモページです。~
----
**インストール [#kcc7fc49]
環境:w2k~
+Subversion1.3.2のバイナリをダウンロードしてきてコピーした。
+Subversion/binへパスを通した。
+日本語メッセージが文字化けしたのでAPR_ICONV_PATHを環境変数にセット。APR_ICONV_PATHはSubversion/iconv。

**cvsからの移行 [#bc59af6f]
cvsからの移行にはcvs2svnというツールを使うらしい。cvs2svn1.3.1を使ってみた(python2.4)。以下引っ掛かったところ。
-shiftjisをを使ってる場合は''--encoding SHIFT_JIS''なるオプションをつければよいらしい。
-sort -Tを呼び出してるとこでエラーになるので(windowsのsortコマンドでそのオプションがないのでエラーになる)、[[GNUのwin32ポートのsortコマンド:http://unxutils.sourceforge.net/]]を呼び出すように書き換えた。
-''cvs rcsfile co''コマンドの呼び出しで~
''cvs [rcsfile aborted]: -q or -Q must be specified before "rcsfile"''
みたいなわけのわからないエラーがでたので''--use-cvs''オプションでrcsfileを使わないようにした。
~
以上の修正で一応通ったような気がする。最終的にはsortの部分を書き換えた上で
 python cvs2svn --encoding SHIFT_JIS --use-cvs -s c:/temp/svn/tksqlite c:/doc/cvsroot/tksqlite
みたいな。最後まで滞りなく進むとかかった時間などのリポートが表示される。
~
~
複数のプロジェクトを一つのsvnリポジトリに納めるには、cvs2svnでダンプしてからsvnadmin loadで読み込めばいいらしい。
 python cvs2svn --encoding SHIFT_JIS --use-cvs --dumpfile tksqlite.dump --dump-only c:/doc/cvsroot/tksqlite
 python cvs2svn --encoding SHIFT_JIS --use-cvs --dumpfile hbmark.dump --dump-only c:/doc/cvsroot/hbmark
 svnadmin create --fs-type fsfs svnroot
 svn mkdir -m "mkdir hbmark" file:///temp/svnroot/hbmark
 svn mkdir -m "mkdir tksqlite" file:///temp/svnroot/tksqlite
 svnadmin load --parent-dir hbmark svnroot < hbmark.dump
 svnadmin load --parent-dir tksqlite svnroot < tksqlite.dump
//最終的にはこうなった
//python cvs2svn\cvs2svn --use-cvs --fs-type=fsfs --encoding=SHIFT_JIS --dumpfile ./tksqlitedump.log --dump-only --symbol-transform version-(\d+)-(\d+)-(\d+):version\1.\2.\3 --symbol-transform version-(\d+)-(\d+)-branch:version\1.\2-branch --symbol-transform version-(\d+)-(\d+):version\1.\2 c:/doc/cvsroot/tksqlite

リポジトリのレイアウトの仕方は適当っぽい・・・。プロジェクト毎にリポジトリを作ってもいいし、一つのリポジトリに複数のプロジェクトを登録してもいい。どういうのが適切なのかよくわからんが、プロジェクト名の下にtrunk,tags, branchesを作るというのは一応広まってる慣習のようだ。上の例はプロジェクトごとにリポジトリを作る。どっちがいいのかについては[[「プロジェクトの追加」:http://subversion.bluegate.org/doc/ch05s04.html]]に両方の利点と欠点が書いてある。レイアウトを決めるときは最初に注意深く計画してくださいみたいなことも書いてある。%%つうかそういう計画が行き当りばったりだからcvsやめてsvnにしようと思ってるのに・・・。%%どっちがいいんだろうなあ・・・。


**ディレクトリ構成 [#yfc45665]
svnではタグやプランチを管理するために、
 projname
     trunk
     tags
     branches
のようなディレクトリ構成になっていて、開発はtrunkで行うらしい。チェックアウトするときはこれらのパスに従い、svn co file:///path/to/projname/trunk とかsvn co file:///path/to/projname/trunk projnameとかいうふうにこのディレクトリへのパスを指定する。枝分れしたブランチにタグを付けたりした場合も、projname/tagsに入れるのかな


**とりあえず良く使うコマンド [#h63134bc]
-登録(リポジトリの作成)~
 svnadmin create /path/to/proj
 svn mkdir file:///path/to/proj/trunk
 svn mkdir file:///path/to/proj/tags
 svn mkdir file:///path/to/proj/branches
 cd path/to/proj
 svn import file:///path/to/proj/trunk
リポジトリにプロジェクトを登録する。''svn import [<パス>] URL''はパスが省略されたらカレントディレクトリでインポートする。


-チェックアウト~
 svn checkout(co) file:///path/to/proj/trunc
 svn checkout(co) file:///path/to/proj/trunc proj
パスはfile:///みたいなURLで書く。チェックアウトしたディレクトリ名はpathの最後のディレクトリ名だが、dirで出力先のディレクトリ名を変更することが出来る。~
タグ、ブランチはtags,branches以下にコピーしたリポジトリなので(慣習的にtags,branches以下にタグ、ブランチを作ることになってるらしい)、それらをチェックアウトする時はただ、そのパスを指定するだけ
 svn co file:///path/to/proj/tags/version1.0 proj
みたいな。


-ファイルやディレクトリの追加、削除、リネーム~
 svn add path              ファイルの追加
 svn mkdir path            ディレクトリを作成してaddする
 svn delete path           ディレクトリやファイルを削除する
 svn move oldname newname  リネーム、移動
deleteはファイルはすぐにワーキングディレクトリから消えるが、ディレクトリはコミットするまで残ってるらしい。deleteもmoveもリポジトリに反映させるにはコミットが必要。


-マージ~
 svn merge -r M:N file:///path/to/proj/branches/version0.9
 svn marge file:///path/to/revM file:///path/to/revN
上の例ではversion0.9のブランチでリビジョンMからNの差分をとって、それを現在のワーキングディレクトリに適用する。-r M:Nでリビジョン番号を調べなければならないのがめんどくさい。下の例では、二つのマージ元の差分をとって現在のワーキングディレクトリに適用する。下の例はリビジョン番号を調べないでいいので、タグで管理するときに便利だと思う。~
つうかtrunkとbranch/version2.1の二つの枝で作業を継続する場合、片方の変更をマージするときに-r M:N形式で二つのリビジョンを指定する場合、一番最初に変更した場合は、BASEとHEADの差分をマージしてコミットすればよいのだが、さらに追加で変更し、マージする場合、''最後にコミットしたリビジョン番号を知らなければならない''のが超使いにくい。たとえば最後にコミットしたのがr100でこの時はHEAD=100なわけだが、さらに追加で変更が加わり現在のHEAD=150の場合、-r 100:HEADと書かねばならない。このリビジョン番号100というのを知るために、''「コミット時のコメントに書いておけ」''というのが公式の見解らしいが、なんか納得できん・・・。リビジョン番号の別名としてタグが使えればいいのにと思うのだが。。結局いまのとこマージする前には必ずtagsにコピーを作ることにして、例えば、trunkとbranches/version2.1で作業するとして、branches/version2.1でバグ修正をして、それをtrunkにマージする場合は、branches/version2.1での変更をコミットしたら、直後にコピーのtags/version2.1.1を作り、二つ目の構文(二つのURLの差分をマージする)を使って、tags/version2.1とtags/2.1.1の差分をマージするように使っている。次に変更をマージする時も同じようにtags/version2.1.1とtags/version2.1.2の差分をマージする。こうすればリビジョン番号を知らないでもよいので少し楽な気がする。ただコミットログの情報が分散してしまうのがつらい。
つうかtrunkとbranch/version2.1の二つの枝で作業を継続する場合、片方の変更をマージするときに-r M:N形式で二つのリビジョンを指定する場合、一番最初に変更した場合は、BASEとHEADの差分をマージしてコミットすればよいのだが、さらに追加で変更し、マージする場合、''最後にコミットしたリビジョン番号を知らなければならない''のが超使いにくい。たとえば最後にコミットしたのがr100でこの時はHEAD=100なわけだが、さらに追加で変更が加わり現在のHEAD=150の場合、-r 100:150にしなければならない。このリビジョン番号100というのを知るために、''「マージをコミットするときのコメントにリビジョン番号を書いておけ」''というのが公式の見解らしいが、全然納得できん・・・。リビジョン番号の別名としてタグが使えればいいのにと思うのだが。。結局いまのとこマージする前には必ずtagsにコピーを作ることにして、例えば、trunkとbranches/version2.1で作業するとして、branches/version2.1でバグ修正をして、それをtrunkにマージする場合は、branches/version2.1での変更をコミットしたら、直後にコピーのtags/version2.1.1を作り、二つ目の構文(二つのURLの差分をマージする)を使って、tags/version2.1とtags/2.1.1の差分をマージするように使っている。次に変更をマージする時も同じようにtags/version2.1.1とtags/version2.1.2の差分をマージする。こうすればリビジョン番号を知らないでもよいので少し楽な気がする。ただコミットログの情報が分散してしまうのがいまいちだ。スマートな方法はないものだろうか。


-コミット~
 svn commit 


-ワーキングディレクトリを最新に更新~
 svn update
これはcvs updateと違って、実際にファイルを更新してしまうので、
どれが更新されているか調べるだけの場合は、''svn status''を使う。


-ワーキングディレクトリを他のブランチに変更~
 svn switch path
ブランチを指定してcheckoutするのと同じだけど、差分だけやりとりするのでオーバーヘッドが少ないらしい。


-タグをつけたり~
 svn copy(cp) file:///path/to/proj/trunk file:///path/to/proj/tags/version1.0 -m "version1.0のタグ打ち"
ブランチもタグも同じただのリポジトリのコピーらしい。ブランチはbranchesにタグはtags以下にコピーすると決めた運用ルールでタグとブランチを使い分けてねってことらしい。タグを付けて誤って上書きしちゃったりしたらどうなるのか(まあBASEに戻せばいいのだろうが)。とりあえずは基本は常にtrunkのHEADで作業して、タグやブランチを作る時はcopyしていってねってことらしい。ブランチはコピーでもいいけどタグもコピーってのがいまいち納得できない。。。タグはリビジョン番号の別名みたいな感じで使えればいいのに・・・。あとブランチでバージョンの違う枝をバグフィックスし、パッチ番号を上げた新しいタグを作る場合、自分が作業している枝(ブランチ)のURLを記憶してなければコマンドを打てないのがめんどくさい。


-履歴を見る~
 svn log <option> file    基本はこんな感じ
 svn log -r 170           リビジョンを指定
 svn log -r 170:175       170から175までのリビジョンの履歴
 svn log -r {2006-07-01}  日付は{}でくくる
 svn log -r HEAD          リポジトリで最新
 svn log -r BASE          現在のワーキングディレクトリのベース
''-q''オプションでコメント無しの簡易表示。~
''-v''で変更のあったパスのリストも表示される。


-その他色々情報の取得~
 svn info       現在のワーキングディレクトリの情報を見る
 svn list(ls)   リポジトリ内のls. -Rで子も再帰
 svn status     ワーキングディレクトリの更新情報
 svn status -u  リポジトリの更新情報
 svn status -v  リビジョン番号情報
 svn ls file:///path/to/proj/tags タグの一覧はこうするしかない?


**バックアップなどリポジトリの管理 [#y07fa45f]
-バックアップ~
 svnadmin dump cvnrepos
 svnadmin load svnrepos
リポジトリ全体を標準出力に出力/入力。''--incremental''で差分を出力。
 svnadmin hotcopy old new
リポジトリのコピーを作る。他のプロセスが使用中でも使えるらしい。

-アイテムを消したり取り出したり~
間違えて追加しちゃったり、ゴソゴソsvnを手探りでいじりながらやってると後からあれを消したいとかいうのが必ず出てくる。そんなときはsvndumpfilterを使う。svnadmin dumpの出力を標準入力から流し込んで使う。あるパスを追加したり削除したりしたダンプを出力する。
 svnadmin dump path/to/svnroot/ |svndumpfilter exclude tksqlite> dump.log
みたいな。これは/tksqlite以下のディレクトリをリポジトリから削除したダンプを出力する。また、/tksqlite以下のアイテムだけを出力する場合はincludeを使って
 svnadmin dump path/to/svnroot/ |svndumpfilter include tksqlite> dump.log
みたいな。で、ダンプしたやつを新しいリポジトリにsvn loadで流し込んで作業完了。




**CVSROOTのような環境変数を自動で読んでくれる機能はない [#u07c0c3c]
URLとかパスを書くのがめんどくさい。~
http://svn.haxx.se/users/archive-2005-07/0303.shtml
によれば、環境変数にSVNROOTをセットしとけばいいじゃんってことらしい。
まあそうかな・・・。


**.cvsignore? [#pe363c67]
cvs2svnだとなんかしらんが勝手に.cvsignoreを読んで設定してくれてるみたいだ。~
~
 svn propdel <属性名> [<パス>...] 
 svn propedit svn:ignore .     エディタが立ち上がるので編集して保存する
 svn propget svn:ignore <path> 属性の表示。
 svn proplist -v src           -vで付加情報表示。srcディレクトリのproc表示。
 svn propset svn:ignore . -F .cvsignore .cvsignoreを読み込み

これらで設定した属性情報はディレクトリの属性変更としてコミットすることになる。


**リンク [#q959d60c]
-Subversion http://subversion.tigris.org/
-cvs2svn http://cvs2svn.tigris.org/
-UNIX USER 2003 8: Subversionで管理せよ (draft) http://ukai.jp/Articles/2003/uu-svn/

|New|Edit|Diff|History|Attach|Copy|Rename|
HTML convert time: 0.003 sec.