git-svn から git への移行方法

前回 git-svn を使って、Subversion のリポジトリと連携 の続きです。
git-svn を使っていたのですが、私が最初に設定をエレコマのリポジトリSubversion)の trunk 以下を取得するようにしていたんですね。でも、エレコマの開発者の方は、最新のソースを branch にコミットしたりしていて。そうすると、私たちのチームで開発中のソースと、最新のソースのマージが出来ないわけです。そんな状態で途方にくれていたら、エレコマの開発者の方が、リポジトリを Git に移行してくれました。
ただ、ここからが問題。ただエレコマのソースを取得するだけなら git clone で済みますが、すでに git-svn で取得したエレコマのソースに手を入れている状況です。エレコマのリポジトリSubversion の時は、変更を git-svn rebase で取得できましたが、今度はエレコマの Git のリポジトリから git pull して取得するようにしたいのです。でも、それってできるの?ということで行き詰まりました。
いろんな方法を試して、できたのが下記の手順です。

ローカルに取得しているリビジョン番号を指定して、master ブランチにマージする

git-svn で取得していた最新のリビジョンにあたる、エレコマの Git リポジトリのリビジョンを、最新ソース取得用のリポジトリ(/var/git/elecoma)にマージします。いきなりマージしてしまうとコンフリクトが起こりまくるので、一旦 git fetch してからマージを行います。
まず、master ブランチを エレコマの Git リポジトリと同様にする必要があるので、master ブランチに checkout してから作業を行います。

[root@hoge ~]# cd /var/git/elecoma
# master ブランチに移動
[root@hoge elecoma]# git checkout master
# エレコマの Git リポジトリから、ソースを取得
[root@hoge elecoma]# git fetch git://git.sourceforge.jp/gitroot/elecoma/elecoma.git master
# ローカルに取得しているリビジョン番号(git log とかで確認しておく)を指定してマージ
[root@hoge elecoma]# git merge 55be40069b3d3e837836d9260fbdb7d2c9be6ba2
Merge made by recursive.

FETCH_HEAD を master ブランチにマージする

ちなみに FETCH_HEAD とは、最後にフェッチされたブランチの先頭の簡略記法。フェッチ操作の直後にだけ有効。というものなので、先ほどフェッチしてきたものを、最新ソース取得用のリポジトリ(/var/git/elecoma)にマージする事になります。

[root@hoge elecoma]# git merge FETCH_HEAD
Merge made by recursive.
 app/controllers/cart_controller.rb       |    1 +
 config/locales/translation_ja.yml        |    3 +++
 spec/controllers/cart_controller_spec.rb |    8 +-------
 spec/fixtures/customers.yml              |    2 ++
 spec/fixtures/products.yml               |    5 +++++
 5 files changed, 12 insertions(+), 7 deletions(-)

最新になった master ブランチを dev ブランチに取り込む

今度は、私たちが開発している dev ブランチとのマージです。ここまでくればただ単に master ブランチと dev ブランチをマージするだけです。

# dev ブランチに移動
[root@hoge elecoma]# git checkout dev
[root@hoge elecoma]# git merge master
Auto-merging app/controllers/cart_controller.rb
Auto-merging config/locales/translation_ja.yml
Auto-merging spec/controllers/cart_controller_spec.rb
Auto-merging spec/fixtures/customers.yml
Auto-merging spec/fixtures/products.yml
Merge made by recursive.
 app/controllers/cart_controller.rb       |    1 +
 config/locales/translation_ja.yml        |    3 +++
 spec/controllers/cart_controller_spec.rb |    8 +-------
 spec/fixtures/customers.yml              |    1 +
 spec/fixtures/products.yml               |    5 +++++
 5 files changed, 11 insertions(+), 7 deletions(-)


これでコンフリクトなく、完了!長い道のりでした。ほんとに。

下記はメモです。今回参考になりました。

◆FETCH_HEAD
リモートリポジトリが使われている場合は、git fetch はフェッチしたブランチの先頭をすべて、.git/FETCH_HEAD に記録します。FETCH_HEAD は、最後にフェッチされたブランチの先頭の簡略記法であり、フェッチ操作の直後にだけ有効です。
ブランチに特定の名前をつけない匿名フェッチの場合でも、このシンボリック参照を使って git fetch されたコミットから HEAD を見つけることができます。

●git fetch
リモートリポジトリから、オブジェクトとそれに関連したメタデータを取得します。
●git pull
git fetch と似ていますが、それに加え、対応するブランチに変更をマージします。
●git push
オブジェクトとそれに関連したメタデータをリモートリポジトリに転送します。
●git ls-remote
リモート内の参照を表示します。