Mac OSXでsvkを使ってRubyをハックする。
はじめに
最近、ruby(MRI) の Readline モジュールの libedit 対応や rdoc の記述を行っています。しかし、私は ruby のコミッタではないので、作業の成果を trunk には反映できません。パッチを作成しては ruby-dev ML に報告し、それを revert して rdoc を記述する、といったことをしています。さすがにこれは面倒なので続きません。
そこで、SVK を使って、パッチの作成や変更点の管理を試してみたいと思います。
私の手元の環境は、Mac OSX 10.5 でパッケージ管理システムに Fink を使っています。残念ながら MacPorts ではありません。移行に失敗しました。
Fink の SVK をインストールし、ruby のレポジトリをミラーし、パッチの作成やローカルへのコミットを行ってみます。
SVK のインストール
Fink を使って SVK をインストールします。関連するパッケージが多く、結構時間がかかりました。
ragdoll$ sudo fink install svk
SVK を使用する環境を初期化します。
ragdoll$ svk depotmap --init Repository /Users/kouji/.svk/local does not exist, create? (y/n)y
Rubyのレポジトリのミラー
ruby のレポジトリは大きいため、ミラーするのは trunk の最新のコミットログのみとしました。こうすることで短時間(2、3分)でミラーが完了しました。
ragdoll$ svk mirror //mirror/ruby/trunk http://svn.ruby-lang.org/repos/ruby/trunk Committed revision 1. ragdoll$ svk sync //mirror/ruby/trunk -s HEAD Syncing http://svn.ruby-lang.org/repos/ruby/trunk Retrieving log information from 18233 to 18233 Committed revision 2 from revision 18233.
作業用のブランチの作成
ragdoll$ svk copy -p -m 'copied "ruby/trunk" from mirror to local.' //mirror/ruby/trunk //ruby/trunk Committed revision 3.
チェックアウト
私が使用している Emacs で使いやすいように、普段は svk コマンドではなく svn コマンドを使うことにしました。これで準備が整いました。
ragdoll$ svn co file:///Users/kouji/.svk/local/ruby/trunk svk-trunk A svk-trunk/complex.c ... U svk-trunk Checked out revision 3.
ローカルへのコミット
早速、Readline モジュールへのパッチをコミットしてみます。無駄かもしれませんが、 ChangeLog も書いてみました。
ragdoll$ svn log -v --limit=1 ------------------------------------------------------------------------ r4 | kouji | 2008-07-28 00:10:24 +0900 (Mon, 28 Jul 2008) | 20 lines Changed paths: M /ruby/trunk/ChangeLog M /ruby/trunk/ext/readline/extconf.rb M /ruby/trunk/ext/readline/readline.c A /ruby/trunk/test/readline/test_readline_history.rb * ext/readline/extconf.rb: checked to have clear_history in readline library. * ext/readline/readline.c (hist_get, hist_each, Init_readline): The offset specified for the argument of history_get() might be different in GNU Readline and libedit. If use libedit, it was corrected that the computational method of the offset specified for the argument of history_get() when the Readline module was initialized was decided. * ext/readline/readline.c (hist_get, hist_set): If use libedit, accesses first an input content in history when specifies the negative offset for the argument of history_get() or replace_history_entry(). Then checks the offset is negative in ruby. * ext/readline/readline.c (rb_remove_history): When compiling, it corrects it to warning when libedit is used. * ext/readline/readline.c (hist_clear, Init_readline): added Readline::HISTORY.clear method. * test/readline/test_readline_history.rb: added unit test for Readline::HISTORY.
trunkを最新の状態に更新する
trunkの変更をミラーし、ワーキングコピーを最新の状態にします。
ragdoll$ svk sync //mirror/ruby/trunk Syncing http://svn.ruby-lang.org/repos/ruby/trunk Retrieving log information from 18234 to 18234 Committed revision 5 from revision 18234. ragdoll$ svk pull //ruby/trunk Auto-merging (2, 5) /mirror/ruby/trunk to /ruby/trunk (base /mirror/ruby/trunk:2). Conflict found in ChangeLog: e)dit, d)iff, m)erge, s)kip, t)heirs, y)ours, h)elp? [e]
予想していたことですが、 ChangeLog がコンフリクトします。
デフォルトの e(edit) を選択し、コンフリクトしている箇所を修正します。
<1/V1pXiLInG-WGnqamJqeocE+++TI/-Tmp-/svk-merged-csHbe" 48245L, 1551571C written Merged ChangeLog: a)ccept, e)dit, d)iff, m)erge, s)kip, t)heirs, y)ours, h)elp? [a]
コンフリクトを修正したので、デフォルトの a(accept) を選択します。
しかし、ChangeLog のマージは毎回行うことになるので面倒です。なんとかする方法はないのでしょうかね。
G ChangeLog U test/openssl/test_ssl.rb New merge ticket: b2dd03c8-39d4-4d8f-98ff-823fe69b080e:/trunk:18234 Committed revision 6. ragdoll$ cd ~/work/ruby/svk-trunk ragdoll$ svn up U ChangeLog U test/openssl/test_ssl.rb U . Updated to revision 6.
trunkに修正を反映する
残念ながらできません。私は ruby のコミッターではありません。。。いつかコミッターになりたい。
パッチの作成
私の修正をパッチとして取得します。
まずはログを確認し、修正箇所を把握します。該当するのは r4 です。
ragdoll$ svn log -v limit=10 ------------------------------------------------------------------------ r6 | kouji | 2008-07-28 00:22:45 +0900 (Mon, 28 Jul 2008) | 5 lines Changed paths: M /ruby/trunk M /ruby/trunk/ChangeLog M /ruby/trunk/test/openssl/test_ssl.rb r5@ragdoll (orig r18234): mame | 2008-07-27 23:33:05 +0900 * test/openssl/test_ssl.rb (server_loop): rescue Errno::EINVAL and Errno::ECONNABORTED. ------------------------------------------------------------------------ r4 | kouji | 2008-07-28 00:10:24 +0900 (Mon, 28 Jul 2008) | 20 lines Changed paths: M /ruby/trunk/ChangeLog M /ruby/trunk/ext/readline/extconf.rb M /ruby/trunk/ext/readline/readline.c A /ruby/trunk/test/readline/test_readline_history.rb
修正内容を取得し、パッチを作成します。パッチのファイル名の「no212」 は、 ruby の ITS(Redmine) の #212 のチケットに対応したパッチという意味です。
ragdoll$ svn diff -c4 > patches/no212.r4.patch
まとめ
これで、 SVK を使って、ローカルの環境で ruby の trunk をハックできるようになりました。ruby のコミッタではないので、一段落した修正をコミットできる環境があるのは非常に助かります。
あとは、 ruby のコミッタになって svk の push を試せばこの文書は完成ですね。(いつのことだか。。。)