Git にパッチを送って取り込まれた話

Git の挙動に変なところを見つけたので、パッチを作って Git のメーリングリストに投げてみたところ、何度かのレビューを経て、無事に取り込まれた

Git に貢献したい人とか、オープンソース開発の流れに興味がある人もいるだろうから、作業の流れを書いておくことにする。

1. バグを発見する

何はともあれ、修正したいところを見つけるところから。

先日、git difftool --dir-diff が便利すぎて泣きそうです という記事を書いたが、difftool --dir-diff の挙動を調べているうちに、一時ファイル書き戻し条件が変なことに気づいた。

手元のバージョンが古いのかとも思ったが、master ブランチでも再現したので、ちょっくら深入りしてみた。git difftool は Perl スクリプトだったので、ソースコードに print を追加しつつ挙動を探っていった。しばらく調べていると、コードの流れも分かってきて、--no-symlinks が指定されたとき (Windows ではこれがデフォルト) にのみ動作がおかしいことに気づいた。

マニアックなオプションで、しかも、Windows でしか発生しないバグ・・・ということで発見されてなかったのだろう。ちょっと修正したら期待通りの結果になったので、これはパッチを送ってみるチャンスである、と思い立った。

パッチを作るための手順は Documentation/SubmittingPatches に記載されている。この手順に従って、パッチを送ってみることにした。

2. テストコードを修正する

Documentation/SubmittingPatches を読んでいると、テストコードも一緒に修正しろ、とある。

Windows 上でテスト環境を作ろうとしたが、修羅の道っぽかったのですぐに諦めた。次に、レンタルサーバーを借りている sakura の FreeBSD 上で試そうとしたが、これも罠にハマって解決能力がないので諦めた。

結局、素直に仮想端末に CentOS を突っ込んだ。yum でいろいろインストールしたら、あっさりテストまで実行できる環境ができあがった。

テストはシェルスクリプトで記述されている。シェルスクリプトは不慣れなのだが、しばらく読んでるうちに作法が分かってきたので、真似をして修正した。

3. コミットログを書く

これが一番難しかった。

Documentation/SubmittingPatches を読むと、「修正前は何がおかしかったのか」「修正によって正しくなった理由」を説明することを求められている。もちろん英語で。

実際に、Git プロジェクトのコミットログを読んでみると、どれもコミットログが長くて、しっかりと修正の内容が説明されている。

しかし、自分には英語力がないので、言いたいことをうまく伝えられない。

第一稿では、同一ファイルへの過去のコミットログを切り貼りしつつ、なんとかそれっぽく書き上げたつもりになった (これが後々、「分かりにくいぞ」とツッコミを受けてしまうのだが・・・)。

あとは、コミットログの末尾に Signed-off-by: として自分の名前を書かなきゃいけない。「本名を書け」とあるので、名前を出したくない人にとっては厳しい関門かもしれない。

4. メーリングリストにパッチを投げる

Git の議論やパッチのレビューはすべてメーリングリスト上で行われている。ということで、次にすべきはパッチを Git ML に投げることである。間違っても、GitHub 上で pull リクエストを出してはいけない。

メールを送付する手順も Documentation/SubmittingPatches に書いてある。

まずは、git format-patch でパッチを作成する。作成したパッチはメール形式になっているので、これをそのままメールとして送る必要がある。

自分は GMail を使いたかったので、git-format-patch(1) の MUA-SPECIFIC HINTS に従って、git send-email コマンドを使って送信した。事前に .gitconfig[sendemail] に色々と設定を書くのだけど、最初、[sendmail] に設定を書いてしまってうまくいかずにしばらく悩んだのは、今となってはいい思い出。

5. レビュー結果に従う

しばらく待っているとメーリングリストに返事が届いた。

今回の修正では、コードについては文句が出なかったが、コミットログが分かりにくい、という注文がついた。

1 回目は John さんから、2 回目はメンテナの濱野さんから。

結局、2 回、コミットログのみを書き換えてパッチを再送信した。

三度目の正直、v3 で OK をもらえた。

6. ブランチを昇格していく

OK をもらったコミットは pu (Proposed Update) ブランチに取り込まれる。

しばらく経って異論が出なければ next ブランチにマージされて、最後に master ブランチにマージされる。

最終的に自分のコミット が v1.8.3.2 で取り込まれてリリースされた。リリースノートの末尾にも自分のパッチの情報が書いてあった。

 * "difftool --dir-diff" did not copy back changes made by the
   end-user in the diff tool backend to the working tree in some
   cases.

めでたい。

まとめ

以上でパッチを送ってから取り込まれるまでの流れを振り返った。

印象的だったのは、コミットログをしっかり書かせる文化である、ということ。今回の自分のコミットは「ソースコードの行数 < コミットログの行数」だった。ソースコード上のコメントは少なくても、コミットログにしっかりと歴史や意図が刻まれている。

あとは、英語をなんとかしたい・・・。