ブランチメンテナンスの戦略

Ruby 1.9.1のメンテナンスを引き受けた当初、メンテナンスの指針として参考にできるものは多くはなかった。Ruby 1.8系のやり方を参考にしたくて、いくつか卜部さんに教えを乞うたりもした。そんなこんなで、メンテナンスする中で分かってきたこともあるのでメモする。

目標

まず、リリースブランチをメンテナンスする目標は何であるかをはっきりさせよう。メンテナンスによってどういった価値を提供するかと言っても良い。

安定した仕様の安全に機能するソフトウェアをできるだけ長期間提供すること、これが目標である。永遠に提供できれば良いのだけれども、そうもいかない。利用者が少なくなったバージョンをメンテナンスしてもメリットは少ない。メンテナンスに割ける人手も限りがある。開発されているtrunkとメンテナンスされているブランチが離れるほどにパッチの適用は難しくなり、対処すべき問題を共有することも難しくなる。でも、できるだけ長く提供したい。

この目標を実現するために、ソフトウェアの挙動を安定に保ちつつ、ブランチに残っているバグを解消することを目指す。特に、セキュリティーホールは塞がなければならない。けれども、これらはトレードオフの関係になることがある。バグ修正に伴って挙動が変わってしまうことがある。また、現状の仕様そのものがセキュリティ上の問題を孕んでいて仕様変更しないことにはセキュリティーホールが塞がらないこともある。とはいえ、コードを修正しなければ挙動が変わることもないのだから、バグ修正という目標を妨げない限りにおいてパッチ適用は少ないほどよい。

マージ

ブランチメンテナンスで一番多いのはやはりtrunkからのマージである。そのブランチの固有のバグ修正をすべく独自に開発することもあるけれども、マージするケースのほうが多い。

一番開発が活発で「目玉」が多いのはtrunkだ。各モジュールの担当者も主にそこで活動している。だから、trunkでも再現するような問題はtrunkでの修正をそのまま取り込んだ方がよい。

明確なもの

  • 新機能

    新機能はマージしない。

  • SEGV

    RubyにおいてはSEGVは常にバグである。不正なプログラムを入力されたとしてもRubyは例外を発生させて対処すべきであり、そこで処理系が落ちてしまってはいけない。だから、SEGVが報告されたときには修正パッチは常にマージする。

境界線上

  • テストケース

    当初、テストケースの追加はマージしない方針だった。バグ修正ではないからだ。けれども、バグを検出したり、trunkとの症状の違いを探したりする目的でやはりテストケースは多い方がよい。そこで、どうもテストケース追加パッチは適用したほうがブランチを長生きさせるという目的には合致するようだ。

  • インデント

    インデントや余分な空白を修正するものも、マージした方がよい。これらは本質的な修正は何もしていないのだからマージしないでも良さそうだが、後々効いてくる。というのは、インデントや空白の違いでリビジョン管理システムの自動マージに失敗すると、手でマージする羽目になるからだ。手作業すればミスが発生する可能性が出る。だから、手作業は少ないほど良い。そのためにはインデント修正はマージすべきだ。インデント修正の前後ではGNU indentを使って空白以外の違いがないことを確認する。

  • ドキュメント修正

    決定的な誤解を招くような間違いを修正したケースはマージする。利用者が利用するための環境を含めてソフトウェアだ。

    ただし、修正前でも解釈できるケース、特にスペルミスはマージしない。利用者の頭脳による修正機構を含めてソフトウェアだ。

  • ドキュメント追加

    ドキュメントが無くても死なないので原則としてマージしない。

    けれども、埋め込みドキュメントをマージした方があとあとパッチの適用が楽になりそうなケースというものはある。そういうときはマージすることはある。