git svn と git rebase

| コメント(0)

git svn を使って手元に git レポジトリを作っておきつつ、git svn dcommit -e でリモートの svn に反映させるという状況で git rebase を使ってみた時のメモ。

まず、どこかに trunk があって、branches/release-11 というブランチで次回のリリースにむけた最終調整をしているとします。次に、ちょっとわけがあって機能を追加するために branches/release-11 から feature ブランチを作ったとします。(ま、trunkから作るべきなんだけどさ。今回はそういう状況に遭遇した)


$ svn cp http://www.example.com/svn/myproj/branches/release-11 \
              http://www.example.com/svn/myproj/branches/feature-A
Commited revision 181

この状況で、release-11 では続々とバグ修正が放り込まれるのですが、ふと、feature-A で作業中の場合にもそのバグ修正が必要になりました。

まぁ、svn だけでやるなら svn log -v $REPOS/branches/release-11 --stop-on-copy して、feature-A を作った後のコミットをsvn merge で吸い上げることになるかとおもいます。

$ svn info | grep ^URL
URL: http://www.example.com/svn/myproj/branches/feature-A
$ svn merge -r182:257 $REPOS/branches/release-11
$ svn commit

さて、git-svn な環境だとどうやるのだろうかと実験してみた次第です。手元には git svn init 等でローカルの git リポジトリが作成され、かつ、 svn での変更はすべて fetch 済みとします。前述のように、feature-A は B の時点で fork したけど、release-11 では E--F の修正が行われ、feature-A でもそれらの修正が必要になったとします。


           C---D---G (remotes/feature-A)
          /
  ---A---B---E---F (remotes/release-11)

git svn fetch で svn 側の修正を再確認し、ローカルのブランチをそれぞれ featA と rel11 として作成します。

 $ git svn fetch
 $ git checkout -b featA remotes/feature-A 
 Switched to a new branch "featA"
 $ git checkout -b rel1 remotes/release-11 
 Switched to a new branch "rel11"

この時点で GitXgitk で確認すると以下の様になっているはずです。(B の位置で feature-A は作られたとします。)

           C---D---G [featA](remotes/feature-A)
          /
  ---A---B---E---F [rel11](remotes/release-11)

rebase のために、今の branch を取り込みたい修正を含む側である rel11 にしておきます。

 $ git checkout rel11
 $ git branch
   featA
   master
 * rel11

では rebase で rel11 側の修正を featA に取り込みます。--interactive (-i) は対話的モードで rebase を行うためのオプションです。

 $ git rebase -i featA rel11

再度、GitX か gitk で確認してみるとこんな感じに。しかし、C---D---G---E'---F' の枝には [rel11] とあり、しかもリモート側が設定されていないように見え、不安になります。[freatA](remotes/feature-A)は依然として G の位置にあります。

           C---D---G---E'---F'[rel11]
          /        [featA](remotes/feature-A)
  ---A---B---E---F (remotes/release-11)

なんでかなと思いつつ git svn dcommit -e で変更をリモート側の svn にも反映させます。

 $ git svn dcommit -e

さて、再度 GitX か gitk で確認してみると。。。あら不思議。remotes/feature-A がきちんと rel11 の位置にありますね。

           C---D---G---E'---F'[rel11] (remotes/feature-A)
          /        [featA]
  ---A---B---E---F (remotes/release-11)

rebase っていうんだから、git-rebase のマニュアルにあるように、枝の生えた位置が移動するような様子を GitX や gitk で確認できると思ったのですがちょっと違うんですね。例えば上記の例でも [rel11] というローカルブランチは当初 A--B--E--F だったのが rebase 後には A--B--C--D--G--E'--F' になっていて、これはマニュアルにあるイメージ(下図)と同じ結果なんですが、期待したビジュアルが得られないという。リモートの svn の変更点だけをみると rebase という言葉の響きとは違って、欲しかったコミット(E, F) を merge up しただけということなんですね。ううむ。まだまだ修行が足りないようです。

          A---B---C topic
         /
    D---E---F---G master

After "git rebase master topic", it would be:

                  A'--B'--C' topic
                 /
    D---E---F---G master

Comments

About Me

このブログは Masayoshi Sekimura によって書かれています。現在はサンフランシスコ市内に在住し Six Apart, Ltd. でエンジニアをしています。 このブログ以外にオンラインでやっている事は qootas.org/sekimura/ で見ることができます。 メールは sekimura+blog@gmail.com までどうぞ。

このブログ記事について

このページは、sekimuraがFebruary 25, 2009 5:08 PMに書いたブログ記事です。

ひとつ前のブログ記事は「Gist でのコード埋め込み」です。

次のブログ記事は「svn switch で MovableType をアップグレード」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

Powered by Movable Type 4.26