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"
この時点で GitX や gitk で確認すると以下の様になっているはずです。(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