@kyanny's blog

My thoughts, my life. Views/opinions are my own.

git-svn 利用時にトピックブランチを master へマージするときどの方法が一番良いのか

最近社内に OSQA が導入されて (hiboma++) そこでも聞いてみたんだけどたぶん将来そこに書いたことを忘れると思うのでこっちにも書いておく。コメントもらえたらうれしいです。

git-svn 使っててリモートブランチと対応してるローカルブランチ(git svn info --url で branches/foobar とか出るやつのこと、正式名称わからん)を master にマージするときは --no-ff をつけろ、というのはぐぐるとよくでてくる(--no-ff しない == fast forward してしまうと master の remote url が trunk でなくなってしまうから)

しかしふつうのトピックブランチの場合は remote url は trunk のままなので --no-ff をつける必要はない。必要はないがそのかわりに選択しなければならない。どのように git merge するかで git svn dcommit したときの結果が変わる(git の歴史だけでなく svn の歴史としても)さあ、どれを選べば将来後悔せずに済むだろう?

  • オプションつけない (fast forward)
    • メリット: git のトピックブランチへの各コミットがすべて svn でも個別のコミットとなるので svn log をみたときに各コミットのログと差分が対応して読めるので意図を追いやすい(Trac などで見るとき理解しやすい)
    • デメリット: svn の歴史的には trunk に大量の小さなコミットを行ったことになるのでマージという感じじゃなくなってしまう
  • --no-ff
    • メリット: マージコミットが発生し git svn dcommit すると svn には単一のマージコミットのみが記録されるので svn merge とほぼ同等の結果が得られ svn log (Trac) と相性が良い。 git log でも綺麗に枝分かれてしており見やすい
    • デメリット: svn 側では単一のコミットになる && トピックブランチの各コミットは svn には送られないので細かい変更点のコミットログが svn log (Trac) では読めない
  • --squash
    • メリット: svn に記録される単一のコミットにトピックブランチの各コミットのログも(自分でコピペせず)記録されるので svn log はもっとも完成された感じになる
    • デメリット: git においても単一のでっかいコミットをした扱いになってしまうので git log が悲しいことになる

未来永劫リモートレポジトリに svn を使うつもりなら --no-ff でコミットログを丁寧に編集するのが一番無難なのかなと思ってる、けど将来的に git へ完全移行するつもりなら(おれはそのつもりだ)ふつうに git merge しといたほうがいいのかなという気もする。 --squash は自分でまとめててもないなーというか偏執狂向けだと思った(そうせざるをえない場合もあるのだろうけど)社内勉強会の雑談タイムで同僚にも聞いてみたところ「rebase -i を使えばいいんじゃないの」と言われたが rebase -i についてぜんぜん知らないのでそっちも調べる必要がある。

ちなみに git merge をなかったことにしたいときは git reset --hard ORIG_HEAD を使う(これは Git 使いはよく知っていると思う)そして git svn dcommit -n (--dry-run) というオプションがありこれは見たまんまで svn に何がコミットされるかを(おおざっぱに)見ることができる(実際にはコミットしない)ので git merge のオプションをかえてみて dcommit -n を試してみると svn 的にはそれぞれどういう歴史になるはずなのかが理解しやすい。