git-svn と GitHub を使ったワークフロー

WordPress のプラグイン開発で WordPress.org の Subversion リポジトリと GitHub を使っているのですが、最近ようやく git-svn を使ったワークフローをどうやったら良いかがわかってきたので要点をまとめておきます。

git-svn のワークフローのポイント

基本的なワークフローはここに書いてある通りです。 ポイントは以下の点です。

  • git svn dcommit は master ブランチで行う
  • リリース時に master、remotes/origin/master、remotes/trunk が同じコミットを指すように心がける
  • そのためには、リリース時は git svn dcommit してから git push する
  • Subversion リポジトリへのコミット回数を減らすには git merge –noff を使う。

リンク先記事は英語ですが、コマンドを自分で打ってみれば何をやっているかわかると思います。 –no-ff や –ff オプションについてはこちらの記事がとてもわかりやすいです。 私が WordPress プラグイン開発で使用している具体的なコマンド例についてはこちらの記事をご覧ください。

どこでつまづくのか

git svn dcommit を実行したときに新たなコミットがつくられてしまうので、git のリモートブランチ感覚で remotes/trunk を扱うとまずいのです。 git commit –amend と似た動作と言えばわかるでしょうか。

次の図のようにブランチ master と work が同じコミットを指した状態で master 上で git svn dcommit をすると master と work は分岐した異なるコミットを指すようになります。

git-svn-dcommit
git svn dcommit 時の動作

このような動作なので、Subversion 追跡ブランチを作ってその上で git svn dcommit を行うと master と remotes/trunk が平行する状態になって困ります。 ですので、必ず master ブランチ上で git svn dcommit を行い、その後に git push origin master を行います。 このあたりを意識できないと git-svn をうまく使えません。

既にぐじゃぐじゃなんですけど

では、頑張って直してみましょう。 master ブランチでは Subversion trunk の最新版に更に修正が加わっているものとします。 git svn dcommit 時に reset されてしまうので、差異がないとうまく行かないと思います。

work ブランチを作って master をマージします。 -s オプションでとにかく master を正としてマージします。

$ git checkout -b work trunk
$ git merge -s recursive -Xtheirs --no-ff master

work ブランチ上で作業するのもポイントで、逆に最初 master 上で work ブランチをマージしてしまうと git svn dcommit を実行したときに ‘Transaction is out of date’ と怒られたりします。

必要であれば次のコマンドでメッセージを変更したコミットを作っておきます。 merge の時に –edit オプションを指定しても良いです。

$ git commit --amend

さて、master ブランチを使って git svn dcommit を実行しましょう。

$ git checkout master
$ git merge --ff work
$ git svn dcommit
$ git push origin master

この後 work ブランチは消去してしまっても構いませんし、以下のようにリセットしておいて次のマージ時に使ってもよいでしょう。

$ git checkout work
$ git reset trunk

いかがでしょうか? これでやっと git-svn に悩まされることなく WordPress プラグイン開発に専念できそうです。 この手順は Subversion と Git で平行管理していたソースを統合するときにも使えるように思います。

最後にお約束の宣伝ですが、Standard Widget ExtensionsThin Out Revisions をよろしくお願いします! (まだまだこれからですが、) 着々とユーザーも増えております (SWETOR)。