諸般の事情でRubyのSubversionリポジトリを手元にミラーする必要があり、やってみたら普通に失敗したのでそこからの回復手順をメモ。
Ruby のリポジトリ
Rubyのリポジトリは https://svn.ruby-lang.org/ で提供されており、Subversionリポジトリになっている。GitHub側にもリポジトリは有る https://github.com/ruby/ruby が、こちらは素直な git-svn
ミラーとなっていて、小規模なパッチ向けとしている:
Pull request to https://github.com/ruby/ruby is acceptable for tiny fixes. But pull requests which need discussions will be ignored unless you create a redmine ticket.
svnsync
コマンド
Gitと異なり、SubversionはDVCSではないため、リポジトリの完全なミラーを作るための直接的な方法は用意されていない。代わりに、 svnsync
コマンドで各リビジョンの属性と内容をコピーすることができる。
svnsync
の使い方自体は他に記事がある https://qiita.com/tomy103rider/items/6add817418ced7219231 ので省略。
大きなコミットの取り込みに失敗する
何故か svnsync
は大きなコミットの取り込みに失敗することがある。これは特にRubyのSubversionリポジトリに限ったことではなく、ある程度の規模のリポジトリではそれなりに発生する気がする。... VCSとしてそれはどうなんだ という気もするが。。
失敗した場合は E175002
のエラーコードを表示して失敗する。エラーメッセージは異なるかもしれない。
svnsync: E175002: REPORT request on '/repos/ruby/!svn/rev/58595' failed
失敗からの回復
この失敗から回復するには、手動で同じコミットを再現してやる必要がある。最近のSubversionには、リモートのリポジトリをダンプできる svnrdump
コマンドが有り、これで問題の有るリビジョンをダンプした上で svnadmin
で取り込むという手順となる。
Rubyのリポジトリの場合、ここで回復しても別のリビジョンで失敗した(後述)。その度にこの操作をリビジョンを替えて繰り返している。
手動投入するリビジョンを svnrdump
で取得する
↑のエラーメッセージを見ると、失敗したリビジョンは 58595
であることがわかる。というわけで、 svnrdump
コマンドを使ってこのリビジョンをファイルにダンプする。( r
に注意: ローカルのリポジトリをダンプする svndump
コマンドも存在する。)
$ svnrdump dump -r58595 --incremental http://svn.ruby-lang.org/repos/ruby > dump
この直前のリビジョンまでは svnsync
で取り込めているため、 --incremental
オプションを使える。
ダンプを svnadmin
でロードする
svnrdump
によって生成されたダンプは svnadmin
でミラー先にロードできる。
$ svnadmin load /cygdrive/f/svnmirrors/ruby < dump
...
* パスを編集しています : trunk/spec/rubyspec/shared/time/strftime_for_time.rb ... 完了しました。
* パスを編集しています : trunk/spec/rubyspec/spec_helper.rb ... 完了しました。
------- リビジョン 58595 をコミットしました >>>
svnsync
用のrevpropを手修正する
svnsync
ではミラー先のSubversionリポジトリでのリビジョン 0
のrevpropを使用してsyncの状況を管理している。このため、手動でリビジョンを取り込んだ場合は手でこれらのrevpropを手修正する。
修正が必要なrevpropは、 svn:sync-last-merged-rev
と svn:sync-currently-copying
の2つとなる。
-
svn:sync-last-merged-rev
の修正 → Dumpのリビジョンである58595
にセットする
$ svn propset --revprop -r0 svn:sync-last-merged-rev 58595 file:///cygdrive/f/svnmirrors/ruby
属性 'svn:sync-last-merged-rev' がリポジトリのリビジョン 0 に設定されました
-
svn:sync-currently-copying
の削除
$ svn propdel --revprop -r0 svn:sync-currently-copying file:///cygdrive/f/svnmirrors/ruby
属性 'svn:sync-currently-copying' をリポジトリのリビジョン 0 から削除しました
失敗するリビジョンの傾向
手元でRubyのリポジトリをコピーしてきたときは、 58595
59979
62526
の各リビジョンが失敗した。このリビジョンを見てみると:
- https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=58595
- https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59979
- https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62656
全てが ruby/spec
の取り込みであることがわかる。これらのコミットはいずれも3000以上の変更を含んでおり、svnsync側の秘孔を突く何かが有るのかもしれない。