Blog

GitHubにホストしていたレポジトリをWordPress.orgのSVNにSourceTree(Mac)を使ってプッシュするまで

Posted by admin at 7:09 日時 2013/09/26

一度やってみようと軽い気持ちではじめた、GitHubでホストして開発していたReally Simple CSV ImportプラグインのレポジトリをWordPress.orgのSVNにプッシュするまでの軌跡をメモ程度に。この記事の要約です:

  1. Gitでスタートしたレポジトリも、git-svnを使えばSubversionのレポジトリにプッシュできる!
  2. ただし、Submodulesを使うのはダメ、絶対
  3. Mountain Lionを使っているとgit-svnが動かなくてはまる

Git svn を動かす

事前調査でググってみたところ、どうやらGit側に git svn というGitからSubversionにコミットできるツールがあってそれを使うのが王道ということなので、まず git svn が使えるかを確認してみる。すでにGitは導入済みだったのでgit svnも入っていたのですが、エラーがでて動かない。

Can't locate SVN/Core.pm in @INC (@INC contains:

これもググってみると、バージョン10.8からのMacOS XはPerlのSubversionライブラリーを含まないようになったので、動かすにはXcode Command Line Toolsをインストールする必要があるようです。また、Xcodeの位置も /Developers から /Applications に変わっているので注意した方が良いですね。

Xcodeを開く → [Xcode] メニューから [Preferences…] を選択 → [Downloads] タブで [Command Line Tools] をインストールする

そのあとパスを通さないと行けないという記事もあったのですが、自分の場合は再起動するだけでコマンドが通りました。

Git svnを既存のレポジトリで使うための初期設定を行なう

既存のSubversionレポジトリからfetchしてGitに移行し、それ以降はGitで運用するという記事はたくさん見かけたのですが、今回はすでにGitレポジトリとして運用開始しているものをSubversionに持って行きたいので、そのままでは使えませんでした。このような用途の場合は、git svn init コマンドを使うようです。以下、SourceTreeを愛用しているのでSourceTreeで説明しますが、通常のコマンドからの使いかたでも基本は同じだと思います。

まず、SourceTreeでブックマークを開き、Terminalボタンをクリックしてレポジトリのディレクトリでターミナルを開きます。

次に、下記コマンドでGitレポジトリをgit svnで使うための設定をします(プラグイン名は各自変更してね)。

$ git svn init -s --no-minimize-url http://plugins.svn.wordpress.org/really-simple-csv-importer/

-s または –stdlayout オプションは、タグやブランチのディレクトリ構造を標準的なレイアウトで使用するというオプションで、WordPress.orgのSVNはこれに従っていますので、このオプションをつけておくと設定が楽です。

–no-minimize-url オプションは、URLで指定した自分のプラグインディレクトリー以外を見に行かないようにするために必須らしいです。

git svn initを実行すると、.git/config ファイルに設定が追記されます。

  [svn-remote "svn"]  	url = http://plugins.svn.wordpress.org/really-simple-csv-importer  	fetch = trunk:refs/remotes/trunk  	branches = branches/*:refs/remotes/*  	tags = tags/*:refs/remotes/tags/*  

次に、WordPress.orgのSVNからfetchしておきます。

$ GIT_TRACE=2 git svn fetch

これが、ハングアウトしたのかと思うくらい時間がかかります。どうやら、WordPress.orgのSVNの全コミットを走査している模様。マジかよ…今後プラグインが増えるとますます重くなるってことじゃないですか…。

git svn init が完了していれば、SourceTreeeからFetchしても自動で git svn fetch で取ってきてくれるのですが、あまりに時間がかかって不安になるので、GIT_TRACE=2 オプションを先頭につけてログを見ながらターミナルで実行するのがオススメ。

Subversionからチェックアウトする

ここでいったんターミナルは閉じて、SourceTreeに戻ります。左サイドの [REMOTES] メニューに「Subversion」が追加されていますので、trunkブランチを右クリックしてメニューから [Checkout…] をクリックします。

表示されるウィンドウで [Checkout remote branch:] は [trunk] を選択、チェックアウト先にはSubversionと同期するためのブランチを新しく作ります。[New local branch name:] に分かりやすく “svn” と入力します。ちなみに、trunkの場合はリモートブランチと同じ名前だとエラーになるみたい。

ブランチが作成できたら、SVNのtrunkをtrackするように設定します。

▼ログ

git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree branch --set-upstream svn trunk    Branch svn set up to track local ref refs/remotes/trunk.    Completed successfully

Subversion追随用のブランチにmasterブランチのコミットをマージする

以上でSubversionに追随するためのブランチができましたので、すでにコミットして運用しているmasterブランチから新しく作ったブランチにマージします。

SVNにはまだ何のコミットも無いので、マージは問題なく完了します。それでは、いよいよWordPress.orgにプッシュします。

追記

2回目以降、マージは –squash オプションをつけて、1つのコミットにまとめることにしました。svnとmasterが完全に別ルートになるので、svn側のコミットはリリースごとに行なうことにすれば、コンフリクト時なども楽になると思います。

git merge --squash master

SVNにプッシュする

プッシュするのはかんたんで、[Push] ボタンをクリックするだけです。git svn の場合は、プッシュするには git svn rebase と git svn dcommit の2つの手順を踏む必要があるのですが、git svn init が完了していればSourceTreeがその辺の差異は吸収してくれます。

ただし、WordPress.orgの場合はうまく行きませんでした。ログインに失敗して止まってしまいます。

▼ログ

Authentication realm: <http://plugins.svn.wordpress.org:80> Use your WordPress.org login    Username: Use of uninitialized value $username in chomp at /Applications/SourceTree.app/Contents/Resources/git_local/lib/perl5/site_perl/Git/SVN/Prompt.pm line 114.    error: git-svn died of signal 11

設定で回避できるのかな?と思って調べたのですが…

「パスワードを聞くポップアップが出るはずだよ?GitHubとかでしか試してないけど」(意訳)とのことなので、どうもGit-svnではだめっぽいっス。結局コマンドラインから実行することにしたっス。Terminalボタンをクリックし、下記コマンドを実行。

$ git svn rebase

これで準備完了なので、次にコミットします。

$ git svn dcommit --dry-run # <--確認  $ git svn dcommit

ログイン情報が聞かれますので、ターミナルからWordPress.orgのログイン/パスワードを入力します。これで完璧〜!…と思ったらさらに壁が待ち構えていました…

▼ログ

Committing to http://plugins.svn.wordpress.org/really-simple-csv-importer/trunk ...  Authentication realm: <http://plugins.svn.wordpress.org:80> Use your WordPress.org login  Username: hissy  Password for 'hissy':  A LICENSE  A README.md  Committed r776774  A README.md  A LICENSE  r776774 = 010bf4c97e0bc5f62c9383da030f8ebd598e2ee6 (refs/remotes/trunk)  A .gitmodules  A wp_post_helper  af2db033b3d16307607642aa10e983465217063b doesn't exist in the repository at /usr/share/git-core/perl/Git/SVN/Editor.pm line 395  Failed to read object af2db033b3d16307607642aa10e983465217063b at /usr/libexec/git-core/git-svn line 1029

GitのSubmoduleはgit svnでSubversionに送れないのよ!(そんな!)

なんだこのエラーは!?と思ってググったところ、どうもgit svnはSubmoduleに対応していないみたいですね。そりゃそうか…git特有の便利機能ですもんね。うつうつします…

As of Jan 2009 git-svn does NOT work with submodules

git-svn and submodule | de-co-de

2009年の情報と古いですが、他にもググると諦めているひと多数なので諦めることにしました。諦める方法はリンク先とは違い、rebaseを使ってsubmoduleを追加したコミットを消すことにしました。

Submoduleを追加する直前のコミットを右クリックして [Rebase children of xxxxxxx interactively…] 機能でSubmoduleを追加したコミットを削除しちゃいます。

その後、Submoduleではなく普通にファイルをおいてgit addしてコミットします。コミット履歴が変わりリモートのGithubに普通にPushはできなくなるので、ターミナルから強制的にプッシュします。

git push -f origin master:master

Submoduleを諦めるにあたっては下記の記事がたいへん参考になりました。

ついに…コミット…オナシャス!

$ git svn rebase  First, rewinding head to replay your work on top of it...  Applying: Initial commit  ...

 

$ git svn dcommit svn  W: -empty_dir: trunk/LICENSE  W: -empty_dir: trunk/README.md  Committing to http://plugins.svn.wordpress.org/really-simple-csv-importer/trunk ...  ...  r776811 = f9b4729dd174e5f1a06f477d85f27efcfcdc21fb (refs/remotes/trunk)  No changes between current HEAD and refs/remotes/trunk  Resetting to the latest refs/remotes/trunk  dcommitted the branch svn  Completed successfully

できた!

タグを打ってリリース

WordPress.orgのSVNでは、タグを打つと自動でzipのリリースパッケージが作られるそうなので、タグを作ります。SourceTreeでは [Tag] ボタンをクリックするだけです。すると、SubverisonのタグとGitのタグ、どっちを作りたいの?と聞いてきますので、Subversionのタグを選びます。

▼ログ

git svn branch --tag 0.1  Found possible branch point: http://plugins.svn.wordpress.org/really-simple-csv-importer/trunk => http://plugins.svn.wordpress.org/really-simple-csv-importer/tags/0.1, 776811  Found branch parent: (refs/remotes/tags/0.1) f9b4729dd174e5f1a06f477d85f27efcfcdc21fb  Following parent with do_switch  Successfully followed parent  Copying http://plugins.svn.wordpress.org/really-simple-csv-importer/trunk at r776811 to http://plugins.svn.wordpress.org/really-simple-csv-importer/tags/0.1...  r776815 = a5b3ba361844cc3496a47a9c03aae6a6f11b36df (refs/remotes/tags/0.1)  Completed successfully

2回目以降のリリースもリベース

次のリリースも git svn rebase から git svn dcommit の流れなのだが、rebaseの際にコンフリクトが起こるようになってしまった。コンフリクトは通常通りに解消し、git rebase –continue または –skip を行なう。rebaseの再開は git svn rebase –continue ではなく、 git rebase –continue で良いです。

毎度リベースしか手段がないということは、今後毎回コンフリクトするのかな…めんどくさ!

rebaseの参考記事

で、やってみたところ結局svnブランチはmasterとは別ルートでコミット履歴が作られていくので、マージが楽になるという以上のメリットはないのかもしれません。やり方が悪いだけかもしれませんが…。それかもう別ルートならsvnブランチのコミットはsquashつけてまとめた方がいいかもしれんな。

WordPress.orgのSVNはあとassetsディレクトリーに画像ファイルなどをコミットできるのですが、面倒なので誰かが教えてくれるのを待っておこうと思います


Share this entry