SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

あるSVNリポジトリから別のSVNリポジトリに履歴を引っ越す(git svn を利用して部分的に)

問題

以下のような使い方をしているSubversionリポジトリがあります。
(今回はbranches、tagsは無視します)

svn://example.com/svn/
|-- project_A
|   `-- trunk
|-- project_B
|   `-- trunk
`-- project_C
    `-- trunk

project_Bを別のSubversionリポジトリに履歴を含めて部分的に移転したいです。

svn://example.jp/svn2/
|-- AAA
|   |-- project_D
|   |   `-- trunk
|   `-- project_E
|       `-- trunk
`-- BBB
    |-- project_B    # ここに混ぜたい
    |   `-- trunk
    |-- project_F
    |   `-- trunk
    `-- project_G
        `-- trunk

svnadmin dump, svnadmin load ではできなさそうですが、何か手はありますか。

答え

git svn を使って、SVNリポジトリの一部のディレクトリのコミットの内容だけ取得して、別のSVNリポジトリのディレクトリにコミットするということをしてみます。

1.移転先SVNリポジトリに、空のディレクトリだけ作っておく

上の例でいうと、以下のようになる。

$ svn mkdir svn://example.jp/svn2/BBB/project_B
$ svn mkdir svn://example.jp/svn2/BBB/project_B/trunk

2.移転先を git svn clone

$ git svn clone -s svn://example.jp/svn2/BBB/project_B

-s オプションは、SVNリポジトリが trunk, branches, tags のよくある構成だとgitに教えてあげるオプション。trunk などがない場合はオプションをつけなければよい。

この時点で git log すると、移転先はまだ何も履歴がないので、コミットが1個だけポツンとある状態。

3.cloneしてできたワーキングディレクトリに入る

$ cd project_B

4.移転元を追加のSVNリポジトリとして登録し、コミットを取得

–svn-remote で複数のSVNリポジトリを扱える。–prefix も付ける。

$ git svn init -s svn://example.com/svn/project_B --svn-remote=itenmoto --prefix=itenmoto/
$ git svn fetch itenmoto

移転元からのfetchはコミット数によりそこそこ時間がかかるはず。

この時点で、起点となる親を共有していないログが2つある状態になる。

$ git branch -a
master
remotes/itenmoto/trunk ← 移転先。コミット多数あり。
remotes/origin/trunk ← 移転先。コミットが1つしかない。
$ git log
commit xxxxxxxx (HEAD -> master, origin/trunk)
    ← つながってない
commit ed5ffe0b4fce4fc598443c6776051d9b018c25c6 (itenmoto/trunk)
|
commit fce0a6fb7e33b40330fa54b9d7ec64ed59c208b4
|
commit 09887fa331a0d5252994fc66c204ffa93055c583master
|

5.移転先のコミットに、移転元のコミットをつなげたい

origin/trunk の続きとして itenmoto/trunk のコミットが来てほしい。

$ git checkout itenmoto/trunk
$ git rebase origin/trunk

コミットが多いほど時間がかかるので待つ。

Applying: コメント
Applying: コメント
……
……
が続く。

うまくいくとlogがこうなる。

$ git log
commit ed5ffe0b4fce4fc598443c6776051d9b018c25c6 (HEAD)
|
commit fce0a6fb7e33b40330fa54b9d7ec64ed59c208b4
|
commit 09887fa331a0d5252994fc66c204ffa93055c583
|
(略)
|
commit xxxxxxxx (origin/trunk)

以下のようにしてもよさそう。これでmasterの続きに移転元のコミットが来る。

$ git rebase --onto master {itenmoto/trunkの最初のコミット} itenmoto/trunk

6.移転先のSVNリポジトリにコミット

$ git svn dcommit

これもコミットの数が多いほど時間がかかる。待つ。

もっと良い手があるかもしれないけれど、履歴を別のSVNリポジトリの任意のディレクトリに引っ越すことはできた。

メモ

後で気づいたが、コミットした日付が全部今日になっていた。

確かにコミットしたのは今日だけど…日付も含めて移行は難しいか…

関連するメモ

コメント