リリースブランチ

開発者の視点から見ると、 フリーソフトウェアプロジェクトは継続してソフトウェアをリリースしている状態です。 開発者は通常、最新の利用可能なコードをいつも実行しています。 なぜならバグを発見したいですし、 最新だが機能として不安定な領域を避けつつ、 間近なところでプロジェクトの状態を追いかけているからです。 彼らは毎日ソフトウェアのコピーを更新していますが、 一日に一回以上更新することもあります。 よって変更をコミットするときは、 他の開発者も24時間以内にコミットした変更のコピーを入手すると期待できるのです。

では、プロジェクトはソフトウェアをどうやって正式にリリースすべきなのでしょうか。 ある時点のソースツリーのスナップショットを取得してパッケージにまとめ、 たとえばバージョン "3.5.0" として世界中に配布すべきなのでしょうか。 常識からいって答えはNOです。第一、開発ツリー全体が綺麗になっていて、 リリースの準備ができている瞬間なんて多分ありません。 開発を始めた新機能のコードが、様々な完成度でそこらじゅうに転がっているでしょう。 バグを直すために大きな変更をコミットする人もいますが、 その変更には議論の余地があり、スナップショットをとったときには議論中の場合もあります。 この場合、議論が終わるまでスナップショットの取得を遅らせるだけではうまくいきません。 なぜなら、別の関係ない議論がその間に始まってしまう可能性がありますし、 そうなると その議論も 終わるまで待たねばならなくなります。 このプロセスはいつ終わるのか保証できません。

とにかく、ソースツリーの完全なスナップショットを使ってしまうと、 たとえツリーをリリースできる状態にもっていけたとしても、 そのとき進行している開発を妨げてしまいがちです。 たとえば、現在のスナップショットを仮に "3.5.0" とし、 次のスナップショットが "3.5.1" になるとして、 "3.5.1" にはリリース 3.5.0 で見つかったバグの修正が殆ど含まれているとしましょう。 しかし、この両方のスナップショットが同じツリーにあると、 開発者はこのふたつがリリースされている間何をすべきでしょうか? 互換性に関するガイドラインがあるため、新機能を追加することはできません。 しかし、開発者全員が 3.5.0 のコードに入っているバグを熱心に修正するとは限りません。 新機能を完成させようとしている開発者もいます。 リリース作業がソースツリーを不自然な休止状態にする必要があるという理由だけで、 自分が興味がないことに取り組むか、 ぼけっとしているかを選ばねばならなくなったら、開発者は怒ってしまうでしょう。

こうした問題に対する解は、 いつも リリースブランチ を使うことです。 リリースブランチは、バージョン管理システムの単なるブランチ(ブランチ を参照してください)です。 そこでは、リリースされることになっているコードが開発の本線から隔離されます。 リリースブランチの概念は、フリーソフトウェアプロジェクトで生まれたものではありません。 たくさんの商用ソフトウェアの開発チームもリリースブランチを使っています。 しかし、商用ソフトウェアの開発では、 リリースブランチは贅沢なものだと考えられることがあります — つまり、開発チームがメインツリーを安定させる作業を急いでいる間は、 大きな締切に追われて省略されてしまう一種の "ベストプラクティス" になってしまう可能性があるのです。

しかし、リリースブランチはオープンソースプロジェクトに不可欠なものです。 私はリリースブランチ無しでリリースを行っているプロジェクトを見たことがありますが、 いつもぼけっとしている開発者がいる一方で — 通常は少数の — 開発者がリリースを世に出すために働いていたのです。 これは複数の点で悪い結果をもたらしてしまいます。 まず第一に、開発全体の勢いが衰えてしまいます。 ふたつめに、リリースの質が必要以上に下がってしまいます。なぜなら、 開発者は2, 3人しか働いていませんし、 他の開発者が早く開発に復帰できるように急いで作業を終えようとしてしまうからです。 3つめは、異なった仕事が開発者同士を不必要に衝突させてしまうため、 開発者チームが精神的に分裂してしまうことです。 ぼーっとしている開発者は、自分達のスケジュールや興味に沿って行動を選べるのであれば、 リリースブランチに 少し 注意を向けるだけで多分幸せなのです。 しかしブランチがなければ、彼らが選べるのは "俺は今日リリース作業をやろうか、 それとも本線で開発している新機能の作業をしようか?" という二択ではなく、 "俺は今日プロジェクトに参加しようか、それともやめちゃおうか?" となってしまいます。

リリースブランチの使い方

リリースブランチを作る正確な手順は、 利用しているバージョン管理システムに依存しますが、 ほとんどのシステムでは、一般的な概念は勿論同じです。 ブランチは通常別のブランチか、trunk(幹)から派生します。 伝統的に、trunk では本線の開発が進んでおり、リリースの制限を受けません。 リリース "1.0" 用のはじめてのリリースブランチは trunk から派生します。 CVS では、ブランチを作成するコマンドは次のようになります。

$ cd trunk-working-copy
$ cvs tag -b RELEASE_1_0_X

Subversionでは、次のようにします。

$ svn copy http://.../repos/trunk http://.../repos/branches/1.0.x

(これらの例はすべて、3つの数でリリース番号を付けるやり方を想定したものです。 それぞれのバージョン管理システムで使われる正確なコマンドを示すことはできませんが、 CVS と Subversion の例を示すことで、 他のシステムで対応するコマンドが予測できればいいなと思っています。)

"1.0.0" ではなく、 (文字通り "x" という文字を使って)"1.0.x" ブランチを作成したことに注意してください。 これは同じマイナーライン — つまり、同じブランチということです — が全てのマイクロリリースで使われるということです。 リリースのためにブランチを安定させる実際のプロセスについては、 この章の後半の 「リリースを安定させるプロセス」 で説明しています。 ここでは、バージョン管理システムとリリースプロセスの関係にだけ注意を払うことにします。 ブランチが安定し、リリースの準備ができたら、 ブランチのスナップショットにタグを打つときです。 CVS では、次のようにします。

$ cd RELEASE_1_0_X-working-copy
$ cvs tag RELEASE_1_0_0

Subversion では、次のようにします。

$ svn copy http://.../repos/branches/1.0.x http://.../repos/tags/1.0.0

このタグは 1.0.0 がリリースされた時点の、 プロジェクトのソースツリーの正確な状態を表しています。 (これはパッケージ化された配布物やバイナリが削除された後で、 古いバージョンを取得したい場合に役立ちます。) 同じリリースラインでの次のマイクロリリースは、 同じく 1.0.x ブランチ上で準備され、リリースの準備が出来次第、 1.0.1 のタグが打たれます。 1.0.2 に向けて繰り返しブランチを綺麗にしていきましょう。 1.1.x リリースラインについて考え始める時期が来たら、 新しいブランチを trunk から作ります。 CVS では、次のようにします。

$ cd trunk-working-copy
$ cvs tag -b RELEASE_1_1_X

Subversion では、次のようにします。

$ svn copy http://.../repos/trunk http://.../repos/branches/1.1.x

メンテナンスは 1.0.x と 1.1.x ラインに対して並行して続けられ、 リリースは両方のラインから独立して行えます。 実際、ふたつの異なったラインからほとんど同時にリリースが行われることも珍しくありません。 古いラインからのリリースは、 一気に(たとえば)1.1 へバージョンアップしたいときは、 必ず周到な準備をしたいと望む保守的なサイト管理者にお薦めです。 一方で大胆なユーザーは通常、 不安定なバージョンであるというリスクを負ってでも、 必ず最新の機能を使うために、 より新しいラインの最新のリリースを採用します。

ここで説明したことが、リリースブランチの唯一の使い方ではありません。 自分が参加していたプロジェクトではとてもうまくいっていたのに、 ある状況下ではうまくいかないことがあるかもしれません。 うまくいきそうなやり方を使ってください。 しかし、以下の点は重要なので覚えておきましょう。 つまり、リリースブランチの目的は、 日々の開発作業によって生まれる変化からリリース作業を分離することと、 リリース作業を組織的に行うために、 物理的な作業スペースをプロジェクトに与えることです。 このプロセスは次のセクションで説明します。