パッチの送り方

spec ファイルを作成したら、それを Rubinius 開発チームに届けるわけだけど、その手順は次の通り。

  1. spec ファイルをリポジトリに登録する (git add, git commit)
  2. パッチを作成する (git-format-patch origin)
  3. BTS で ticket を発行し、パッチを添付する


まずは、spec ファイルをリポジトリに追加する。これは git add コマンドを使う。git add はファイル名を指定したらそのファイルを追加し、またディレクトリ名を指定したらそれ以下に含まれているファイルをすべて再帰的に辿って追加する。
git add したファイルは、git status で確認できる。

$ cd rubinius.code/
$ cd spec/ruby/1.8/library/erb/util
$ git add h_spec.rb html_escape.rb shared   # 追加
$ git status   # git add したファイル・していないファイルを確認
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   spec/ruby/1.8/library/erb/util/h_spec.rb
#	new file:   spec/ruby/1.8/library/erb/util/html_escape_spec.rb
#	new file:   spec/ruby/1.8/library/erb/util/shared/html_escape.rb
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	spec/ruby/1.8/library/erb/compiler/
#	spec/ruby/1.8/library/erb/def_class_spec.rb
#	spec/ruby/1.8/library/erb/def_method_spec.rb
#	spec/ruby/1.8/library/erb/def_module_spec.rb
#	spec/ruby/1.8/library/erb/defmethod/
#	spec/ruby/1.8/library/erb/filename_spec.rb
#	spec/ruby/1.8/library/erb/new_spec.rb
#	spec/ruby/1.8/library/erb/result_spec.rb
#	spec/ruby/1.8/library/erb/run_spec.rb
#	spec/ruby/1.8/library/erb/set_eoutvar_spec.rb
#	spec/ruby/1.8/library/erb/src_spec.rb
#	spec/ruby/1.8/library/erb/util/u_spec.rb
#	spec/ruby/1.8/library/erb/util/url_encode_spec.rb
#	spec/ruby/1.8/library/erb/version_spec.rb


また操作を間違っても、git reset を実行すれば add したのがすべてご破算になるので、安心して間違ってよい。git reset はちょうど svn revert や hg revert と同じ。ちなみに git revert もあるけど、こちらはすでに commit した checkin を取り消すコマンド。


さて、必要なファイルを add したら、commit する。このときエディタが起動するので、たとえば「Add spec files for ERB::Util.h() and ERB::Util.html_escape()」と入力して保存し、エディタを終了する。

$ git commit   # エディタが起動する
Created commit 830a47b: Add spec files for ERB::Util.h() and ERB::Util.html_escape()
 4 files changed, 102 insertions(+), 0 deletions(-)
 create mode 100644 spec/ruby/1.8/library/erb/util/h_spec.rb
 create mode 100644 spec/ruby/1.8/library/erb/util/html_escape_spec.rb
 create mode 100644 spec/ruby/1.8/library/erb/util/shared/html_escape.rb
 create mode 100644 spec/ruby/1.8/library/erb/util/shared/url_encode.rb


これで spec ファイルがリポジトリに登録されたので、ようやくパッチを作る準備ができた。

パッチを作るには、git-format-patch コマンドを使う。

$ cd rubinius.code/
$ git-format-patch origin
0001-Add-spec-files-for-ERB-Util.h-and-ERB-Util.htm.patch


なんか長いファイル名ができたけど、これが git 用のパッチファイル。中身はこんな感じ。

From 830a47bf771761dfe01498be2e4e402010cddbb9 Mon Sep 17 00:00:00 2001
From: kwatch <kwatch@example.com>
Date: Sun, 10 Feb 2008 01:00:00 +0900
Subject: [PATCH] Add spec files for ERB::Util.h() and ERB::Util.html_escape()

---
 spec/ruby/1.8/library/erb/util/h_spec.rb           |    7 +++
 spec/ruby/1.8/library/erb/util/html_escape_spec.rb |    8 ++++
 .../1.8/library/erb/util/shared/html_escape.rb     |   43 +++++++++++++++++++
 .../ruby/1.8/library/erb/util/shared/url_encode.rb |   44 ++++++++++++++++++++
 4 files changed, 102 insertions(+), 0 deletions(-)
 create mode 100644 spec/ruby/1.8/library/erb/util/h_spec.rb
 create mode 100644 spec/ruby/1.8/library/erb/util/html_escape_spec.rb
 create mode 100644 spec/ruby/1.8/library/erb/util/shared/html_escape.rb
 create mode 100644 spec/ruby/1.8/library/erb/util/shared/url_encode.rb

diff --git a/spec/ruby/1.8/library/erb/util/h_spec.rb b/spec/ruby/1.8/library/erb/util/h_spec.rb
new file mode 100644
index 0000000..142926c
--- /dev/null
+++ b/spec/ruby/1.8/library/erb/util/h_spec.rb
@@ -0,0 +1,7 @@
+require 'erb'
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require File.dirname(__FILE__) + '/shared/html_escape'
+
+describe "ERB::Util.h" do
+  it_behaves_like :erb_util_html_escape, :h
+end
diff --git a/spec/ruby/1.8/library/erb/util/html_escape_spec.rb b/spec/ruby/1.8/library/erb/util/html_escape_spec.rb
new file mode 100644
index 0000000..85069d6
--- /dev/null
+++ b/spec/ruby/1.8/library/erb/util/html_escape_spec.rb
@@ -0,0 +1,8 @@
+require 'erb'
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require File.dirname(__FILE__) + '/shared/html_escape'
+
+describe "ERB::Util.html_escape" do
+  it_behaves_like :erb_util_html_escape, :html_escape
+end
+
diff --git a/spec/ruby/1.8/library/erb/util/shared/html_escape.rb b/spec/ruby/1.8/library/erb/util/shared/html_escape.rb
new file mode 100644
index 0000000..5c71a97
--- /dev/null
+++ b/spec/ruby/1.8/library/erb/util/shared/html_escape.rb
@@ -0,0 +1,43 @@
+shared :erb_util_html_escape do |cmd|
+
+  describe "ERB::Util.#{cmd}" do
+
+    it "escape '& < > \"' to '&amp; &lt; &gt; &quot;" do
+      input = '& < > "'
+      expected = '&amp; &lt; &gt; &quot;'
+      ERB::Util.__send__(cmd, input).should == expected
+    end
+
+    it "not escape characters except '& < > \"'" do
+      input = (0x20..0x7E).to_a.collect {|ch| ch.chr}.join('')
+      expected = input.gsub(/&/,'&amp;').gsub(/</,'&lt;').gsub(/>/,'&gt;').gsub(/"/,'&quot;')
+      ERB::Util.__send__(cmd, input).should == expected
+    end
+
+  end
+
+end
diff --git a/spec/ruby/1.8/library/erb/util/shared/url_encode.rb b/spec/ruby/1.8/library/erb/util/shared/url_encode.rb
new file mode 100644
index 0000000..61289e5
--- /dev/null
+++ b/spec/ruby/1.8/library/erb/util/shared/url_encode.rb
@@ -0,0 +1,44 @@
+shared :erb_util_url_encode do |cmd|
+
+  describe "ERB::Util.#{cmd}" do
+
+    it "encode characters" do
+      #input  = (0x20..0x7E).to_a.collect{|ch| ch.chr}.join
+      input    = " !\"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
+      expected = "%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E"
+      ERB::Util.__send__(cmd, input).should == expected
+    end
+
+    it "encode unicode string" do
+      input = "http://ja.wikipedia.org/wiki/\343\203\255\343\203\240\343\202\271\343\202\253\343\203\273\343\203\221\343\203\255\343\203\273\343\202\246\343\203\253\343\203\273\343\203\251\343\203\224\343\203\245\343\202\277"
+      expected = 'http%3A%2F%2Fja.wikipedia.org%2Fwiki%2F%E3%83%AD%E3%83%A0%E3%82%B9%E3%82%AB%E3%83%BB%E3%83%91%E3%83%AD%E3%83%BB%E3%82%A6%E3%83%AB%E3%83%BB%E3%83%A9%E3%83%94%E3%83%A5%E3%82%BF'
+      ERB::Util.__send__(cmd, input).should == expected
+    end
+
+  end
+
+end
-- 
1.5.3.4


このパッチファイルはカレントディレクトリに作成され、commit ごとに別ファイルとなるようだ。


あとは http://rubinius.lighthouseapp.com/ で ticket を発行し、パッチファイルを添付すればよい。