Life goes on

何かJavaScriptとかVimとかMacとかに関係してそうな深淵から覗かれる者

git-svnを使うときのベストプラクティス

いつもの事ですが、タイトルは釣り。

現在のプロジェクトにアサインされてから、VCSsvnに逆戻りしてしまったのでかれこれ5ヶ月近くgit-svnを使用してます。初めの頃に2~3回程checkoutしなおすレベルの失敗があったりしましたが、ここの所はそれほど問題無く運用してます。

gitとsvnでもう根本の仕組みから全然違うんで、ある程度しょうがないのですが、ちょっとばかり気をつけないとハマる可能性があるので、その点について語ります。

svnがremoteになってるブランチは 絶対 に直接コミットなどしない

自分の中ではこれが鉄則になってます。例えば普通のsvnの構成だと、trunkがgitのmasterブランチになりますが、何かの修正するって時にはどんだけ軽い修正とかでも絶対にトピックブランチを作ってます。

原則として、masterブランチ(や、他のsvnで作ってあるブランチ)には、gitを使用してのコミットはしないというルールを守っています。

gitでの修正はsvnよりもコミット粒度が細かいので、masterに取り込みする時には自分は git merge --squash で全部まとめてマージしています。まとめたものをそのまま、 git svn dcommit してsvn側にコミットするという流れです。

一度、masterブランチでガツガツと git commit しまくったのを、 git svn dcommit したらリポジトリが壊れました。

masterブランチを、トピックブランチに取り込む時には、 絶対git rebase master

上記のように、修正や機能追加でトピックブランチが乱立する訳で、そちらにはmasterがアップデートされた場合に取り込む必要があります。

この際に、 git mergegit rebase かという問題がありますが、gitのみ使用する場合にはどちらにしても単純にそのリポジトリの運用の問題(rebaseだと他のブランチをマージしたコミットがどこなのか分からないとか、mergeだとツリーが1本じゃなくなって汚ないよとか)だからどっちでも良いかなーと考えてますが、事git-svnを使用する場合は git rebase の方がトラブルが無くて良いです。

そもそも論ですが、svnは履歴が一直線になるんで、それに合わせた方が良いという理由なんですが、一度マージしてしまいmergeコミットが出来たのをさらに、masterに取り込もうとしたらリポジトリが壊れました。

まとめ

という事で以上の2点を守れば、そこそこ快適にgit-svnを使えるんじゃないかなーと思っています。忘れてはならないのが、git-svnはあくまでも svnが主役 という事です。gitは脇役です。なので、運用は若干面倒になりますが、gitの流儀を使うのではなく、svnの流儀に合わせるのが肝心なんじゃないかと思ってます。

上記の事を守ってるので、現在4ヶ月程はほとんどトラブルもなく平穏に過ごしています。みなさんの(そんなにいるのか分からんけど)ご参考になれば。

補足:なんでそんな苦労してまで、git-svnを使うのか

これは、gitに慣れてしまっているというだけです。git-svnを使った際にsvnよりも断然便利だという点は以下。

  • git stash が使える
  • 現在の作業を一旦休止して、差し込みの作業を行なうのがgitだと容易。(ブランチ切りやすいから)
  • svnよりもコミット頻度を上げていけるので、いざ元の状態に戻す…という作業が簡単。
  • svnのコマンド忘れた
  • 万が一プロジェクトのリポジトリがgitに移行した場合に、自分のgitリポジトリを使えば移行コストが低い

というような感じでしょうかね。やっぱり、手元では自由にgitでバージョン管理できるというのが素晴しく便利です。

ただ、今一番希望してるのはやっぱりプロジェクトのリポジトリをgitで管理する事ですけど。ベストなのは、GitHubを導入してコードレビューなんかもしやすくなる事なんですけどもねー。