Subversion 1.5への移行

Subversionの1.5より前のバージョンでは、内部ではリビジョン毎に同一ディレクトリにファイルが作成されるため、リビジョン数が大きくなるとかなり不安な状態になってしまう。*1
しかし、バージョン1.5からはshardingという仕組みが導入され、1000リビジョン毎に一階層深いディレクトリにファイルが作られるようになったので多い日も安心。
Improved support for large deployments on FSFS, via sharding


1.5では他にも新しい機能がいくつか追加されており、特にマージ関連の機能追加(Merge tracking)がうれしいのでバージョンアップしたいのだが、古いバージョンのクライアントが混在した場合にどうなるかが不安なので調べてみた。


検証に使用したのは以下のバージョン。

$ svn --version
svn, バージョン 1.5.3 (r33570)
   コンパイル日時: Oct 11 2008, 19:03:46
$ svn --version
svn, バージョン 1.4.2 (r22196)
   コンパイル日時: Mar 14 2007, 20:55:55

それぞれMacPortsCentOS 5.2での最新パッケージ。

Merge trackingを試してみよう

旧バージョンでの検証の前に、とりあえず新機能のMerge trackingを試してみよう。
サンプルとして svn://svn-server/trunk に rails のプロジェクトを作ってみた。

ブランチ作成

[~] $ svn copy svn://svn-server/trunk svn://svn-server/branches/first-test

trunkの作業コピーで適当なコントローラを作成

[~/trunk] $ ./script/generate controller -c login
[~/trunk] $ svn ci

first-testの作業コピーで適当なコントローラを作成

[~/first-test] $ ./script/generate controller -c profile
[~/first-test] $ svn ci

first-testの作業コピーにtrunkをマージ

[~/first-test] $ svn merge svn://svn-server/trunk
--- r2 から r4 までを '.' にマージしています:
A    test/functional/login_controller_test.rb
A    app/helpers/login_helper.rb
A    app/controllers/login_controller.rb
A    app/views/login

おぉ!

さらにtrunkの作業コピーで適当なコントローラを作成

[~/trunk] $ ./script/generate controller -c message
[~/trunk] $ svn ci

もう一度first-testの作業コピーにtrunkをマージ

[~/first-test] $ svn merge svn://svn-server/trunk
--- r5 から r6 までを '.' にマージしています:
A    test/functional/message_controller_test.rb
A    app/helpers/message_helper.rb
A    app/controllers/message_controller.rb
A    app/views/message

おおぉ!
手動でリビジョンを指定したり記録したりする必要がないぞ!


マージしたリビジョンはsvn:mergeinfoプロパティに記録されていた

[~/first-test] $ svn propget svn:mergeinfo
/trunk:2-6

最後にfirst-testブランチからtrunkへのマージ

$ svn merge --reintegrate svn://svn-server/branches/first-test
--- リポジトリ URL 間の差分を '.' にマージしています:
A    test/functional/profile_controller_test.rb
A    app/helpers/profile_helper.rb
A    app/controllers/profile_controller.rb
A    app/views/profile
 U   .

やったー

ただし、ブランチを作成してからtrunkにマージするまでの間にどちらかでディレクトリの移動(名前変更)又はコピーが行われていると、最後のマージで失敗してしまう。

[~/trunk] $ svn merge --reintegrate svn://svn-server/branches/first-test
svn: Cannot reintegrate from 'svn://svn-server/branches/first-test' yet:
Some revisions have been merged under it that have not been merged
into the reintegration target; merge them first, then retry.

その場合は以前と同じ方法でマージを行えば問題ない

[~/trunk] $ svn merge svn://svn-server/trunk@11 svn://svn-server/branches/first-test@11 .

古いバージョンでのマージ

ブランチ作成

[1.5:~] $ svn copy svn://svn-server/trunk svn://svn-server/branches/second-test

trunkの作業コピーで適当なコントローラを作成

[1.5:~/trunk] $ ./script/generate controller -c star
[1.5:~/trunk] $ svn ci

second-testの作業コピーで適当なコントローラを作成

[1.5:~/second-test] $ ./script/generate controller -c bookmark
[1.5:~/second-test] $ svn ci

1.4クライアントでsecond-testの作業コピーにtrunkをマージ

[1.4:~/second-test] $ svn merge -r 17:19 svn://svn-server/trunk
A    test/functional/star_controller_test.rb
A    app/helpers/star_helper.rb
A    app/controllers/star_controller.rb
A    app/views/star

trunkの作業コピーへさらに適当なコントローラを追加

[1.5:~/trunk] $ ./script/generate controller -c anond
[1.5:~/trunk] $ svn ci

1.5クライアントでsecond-testの作業コピーにtrunkをマージ

[1.5:~/second-test] $ svn merge svn://localhost/trunk
--- r17 から r21 までを '.' にマージしています:
A    test/functional/anond_controller_test.rb
A    test/functional/star_controller_test.rb
A    app/helpers/star_helper.rb
A    app/helpers/anond_helper.rb
A    app/controllers/anond_controller.rb
A    app/controllers/star_controller.rb
A    app/views/star
A    app/views/anond

重複してマージが行われてしまった。ファイルに一切変更がなければよきに計らってくれるみたいだけど、何らかの変更があると

--- r17 から r22 までを '.' にマージしています:
A    test/functional/anond_controller_test.rb
A    test/functional/star_controller_test.rb
A    app/helpers/star_helper.rb
A    app/helpers/anond_helper.rb
A    app/controllers/anond_controller.rb
'app/controllers/star_controller.rb' で競合が見つかりました。
選択: 延期 (p), 全差分 (df), 編集 (e),
        ヘルプでその他のオプションを表示 (h) : p
C    app/controllers/star_controller.rb
'app/views/star' を飛ばしました
A    app/views/anond

衝突する。

マージ作業を古いクライアントと混じりながら行う事は考慮されていないようだ。

まとめ

  • Merge trackingは便利
  • ブランチ作るならクライアントも1.5にした方が良い
  • 1.4以前でマージをすると不幸になる

*1:FSFSの場合