[Subversion]過去の分岐の歴史を修正する方法

リビジョンが40,000くらいまで進んだ今頃になって、10,000あたりのsvn logが気になりだしたDQNEOです。
こんにちわ。

過去の不適切な履歴を修正したい

普段のオペレーションでsvn cpやsvn mvを適切に使っていれば、ソースコードの履歴はちゃんと誕生当時にまで遡れるはずですが、 開発メンバー全員が常にsvn cpやsvn mvの意味を認識しているとは限りません。

特にSubversionに不慣れな開発者は、svn cpの代わりに "cpしてsvn add"を、svn mvの代わりに"mvしてsvn add"をするということをやってしまいがちです。
アプリケーションの根幹にかかわらない枝葉末節のファイルであれば気にすることもないのですが、ことフレームワーク部分であったりアプリケーション基底クラスでこれをやられると大問題です。
アプリケーションそのものの歴史が断絶してしまい、成り立ちがわからなくなってしまいいます。

私のプロジェクトではリビジョン10,000番あたりでこれが起こったので、それ以前の履歴を見れなくなってしまいました。
(厳密に言うと、svn blame $URL/trunk@9999 とか svn log $URL/trunk@9999 --limit 10 とかすれば見れるのですが、@でリビジョン指定するのはとても面倒くさい)
svn logやsvn blameで履歴が気軽に見れないのは痛いです。

何とか過去の歴史をただそうと、svnadmin dump & loadを駆使してやってみたら、うまくできたので紹介します。

事例

動機
r40000まで進んだ今になって、r10000のコミットをやりなおしたい。
経緯
例えば、r10000付近で新人プログラマがこのようなコミットをしてしまっていたとします。
# r9999 trunkを丸ごと削除
svn del trunk
svn ci -m "delete trunk"

# r10000 ブランチをcpでコピー
cp branches/hoge trunk
svn add trunk
svn ci -m "new trunk"
(mergeしろよとかそういう話はさておき)

本来"svn cp"しないといけない場面で、"cp & svn add"してしまいました。
このオペレーションの結果、trunkの歴史はr9999以前とr10000以降で断絶してしまいました。

どうしていればよかったのか

r10000のコミットは、こうであって欲しいところです。
svn cp branches/hoge trunk
svn ci -m "copy from branch"
こうであれば、trunkの歴史はbranches/hogeの歴史と共有されますので、trunkの歴史はどんどんさかのぼることができて、branches/hogeが誕生する前のtrunkにまで遡ることができます。
一言でいうと、trunk@40000からtrunk@1まで、歴史が一本の線でつながります。

svnadmin dump & loadで過去の歴史を改ざんする方法

まず、r9999までをダンプ&リストアします。
svnadmin create repo_new
svnadmin dump repo -r 1:9999 | svnadmin load repo_new
次に、svnクライアントを使ってrepo_newをチェックアウトして、自分でコミットします。
svn co $URL_REPO_NEW work
cd work
svn cp branches/hoge trunk
svn ci -m "copy from branch"
やった!これでr10000は自分の思い通りになりました。
あとは残り部分をダンプ&リストアします。
svnadmin dump repo -r 10001:HEAD --incremental | svnadmin load repo_new
これで完成です!
trunk@40000からtrunk@1まで、歴史がつながりました!

これが成功した瞬間、ちょっと泣きそうなくらい感動してしまいました。
Happy Hacking!

参考:http://q.hatena.ne.jp/1345827198
カテゴリ:

人気記事