svndumpfilter は意外と使えない

というのも、svn copy を利用してあちこちの branch で作業したファイルはその branch も include しておかないと途中で svndumpfilter が不正なパスとか文句言って止まっちゃう。こういうファイルが大量にあると include の引数がとんでもないことになってしまう。

結果、構成によるんだろうけど、手元のものは filter 掛ける前とほとんど変わらない状態にしかならなかった。容量で言うと1割ちょいしか減らない。欲しいのはもっとずっと一部なんだけど。うーん。リポジトリの分割って難しいな。svndumpfilter に force オプションとかあればいいのに。それか手作業? それとも revision を細かく指定しながら incremental に dump して cat?

うーん。

試しに dump ファイルを自前でパースして必要な Node-path の含まれる Revision-number だけ吐き出すスクリプトを書いてみた。この結果出力された revision だけを次々 dump していって、新しいリポジトリに load したら目的のものができるだろうか?

まだ実験は続く。

#! /usr/bin/env ruby

rev = 0

while ( line = gets )
  line.chomp!
  if ( line =~ /\ARevision-number: ([0-9]+)\z/ )
    rev = $1
  end

  if ( line =~ /\ANode-path: (.*)\z/ )
    if ( $1 =~ RE )
      puts rev
    end
  end
end

実際に使ったものとちょっと違うので試してないけど、必要なところを直せばたぶん動きます。あれこれめっちゃ決め打ちです。出て来た数字の羅列を uniq してください。たぶんこんな感じ。

ruby SCRIPT dump-file | uniq > DEST

uniq 持ってない人は while の中で rev を配列にツッコんで最後に

puts array.uniq.join( "\n" )

してください。(最初そうやろうとしたけど、瞬時に動作の様子が見れなくてむかついたのでやめたのでした。)

[追記] 厳しい。

必要な revision だけを dump しても結局 revision の完全な状態を再現可能な dump を作成するので意味がない。–incremental を付ければその前の revision からの差分で dump してくれるが、revision 減らそうって言ってるんだからこいつらを load しまくっても正しくリポジトリを復元できない。

可能な対応は、フル dump に対して、関係する path が含まれていない revision あるいは node を削除していく、というスクリプトを作ることか? でもそうすると dump ファイルを自前でちゃんとパースできないといかんな。(上に挙げたものはかなり適当。)それとも完全自動化は諦めるか? うーん、それもつらい。できなくはないと思うけど。基本的には

Revision-number:
Node-path:
Node-path:
..
Revision-number:
..

こういう構成なので、除外したい Node-path や Revision-number を切っていくのは順番になめていくだけで可能。

つーところまで分かったところで、他にやることがあるのでこれは後回し。誰か作ってくれないかしら。

でもなんか新しいリポジトリでは昔の歴史は思い切って捨てるという判断がいちばん正しいような気がしてきた。負けですか?

※ 最終的には手作業での dump ファイル修正を含めて目的の形にリポジトリを分割することができました。

cf.

More