FeatureBranch を翻訳しました。 #agiletokyo

こちらで約束していた通り、FeatureBranch を翻訳しました。ダメダメかもしれませんが、wikiの方に記載しようと思います。

原文はこちら

フィーチャーブランチ

gitやMercurialの様な分散バージョン管理システム(DVCS)の台頭と共に私はブランチとマージ、どの様に継続的インテグレーション(CI)に適合に向けての戦略に関して、より多くの会話を見てきた。
ここ、特にフィーチャーブランチのプラクティスとどの様にCIに適合させるかに関して、少し戸惑いがある。

シンプルな(分離した)フィーチャーブランチ

フィーチャーブランチの基本的な考え方はフィーチャー(またはあなたがその言葉を好むのならばストーリー)の作業を開始する際、そのフィーチャー上で動作する様にリポジトリからブランチを取得することである。DVCSでは、あなた個人のリポジトリにこれを行うが、この種の作業は、中央集中型バージョン管理システム(VCS)でも行っている。

私はこれをダイアグラムで説明するつもりである。私は共有プロジェクトの青色のメインラインと(開発者たちの名前がグリーン牧師とプラム教授なので)紫と緑の2名の開発者を管理している。

私はブランチへのローカルコミットを表現する為にラベルの付いたカラーボックス(例えば、P1とP2)を使用している。ブランチ間の矢印はブランチ間のマージを表し、それらを際立たせる為にオレンジのカラーボックスを用いる。ここでは、メインラインに適用される幾つかのバグフィックスと呼ばれる更新があることを意味している。これらの更新が起こった際、私たちの開発者たちは自分たちのローカルブランチにそれらの変更をマージする。この時間の感覚を与える為に、私たちは各開発者たちと共にここで数日働いており、毎日大体1回自分のローカルブランチにコミットすることを前提にする。

作業内容が正常に動作していることを確かなものにする為に、彼らは彼らのブランチ上でビルドとテストを実行する。

確かにこの記事では私は各コミットとマージが自動ビルドとブランチ上でテストと共に行われることを前提にしている。

フィーチャーブランチの利点は各開発者が自身のフィーチャーに取り組むことが出来、自分以外の開発者による変更から分離されるということだ。彼らは彼らのフィーチャーのフローを中断せずに確実に彼らのペースでメインラインから変更をプルすることが出来る。しかも、それはチームがリリースの為にフィーチャーを選択することさえも許容する。グリーン牧師が時間をかけ過ぎたならば、私たちはプラム教授の変更だけをリリースすることが出来る。また、恐らく私たちはリリースしようとするフィーチャーの動作に確信が持てない為に、プラム教授のフィーチャーを遅らせるかもしれない。このケースでは、私たちは教授にフィーチャーの受入準備が整うまではメインラインに教授の変更をマージしない様に伝えた。これは“さくらんぼ狩り”と呼ばれ、チームはリリース前にマージするフィーチャーを決定する。

この概念は魅力的に見えるが、トラブルが先にある場合もある。

私たちの開発者たちは分離した状態で自分たちのフィーチャーを開発することが出来るが、ある時点で、自分たちの作業を統合しなければならない。このケースでは、プラム教授は容易に彼の行った変更をメインラインに反映出来る。ここでは全くマージは起こらない。何故なら、彼は既に彼のブランチにメインラインの変更を反映している(ビルドもしているだろう)ためだ。しかしながら、グリーン牧師にとって物事はそう単純ではない。彼は彼の行った全ての変更(G1-6)とプラム教授の行った全ての変更(P1-5)をマージする必要がある。

(この時点でDVCSの多くのユーザたちは恐らくフィーチャーブランチのシンプルで単純なビューの何かを私が見逃していると感じるかもしれない。後でより複雑なスキームを説明しよう。)

これは恐ろしいマージなので、このマージは大きなボックスで示した。開発者たちは意思の疎通なくコードベースで完全に別々の部分に取り組んでいる場合、マージは順調に進み、問題ないかもしれない。しかし、ここの(lye dragons)のケースでは、彼らは相互に作用する部分に取り組んでいるかもしれない。

竜たちは様々な形態で現れることが出来、そして、ツールはそれらの幾つかを倒すのを助けることが出来る。明白な竜の大部分は開発者たちが同じファイルを編集している最中に、ソースコードをマージしたり、コンフリクトに対処することの複雑性である。最新のDVCSは実際にかなり上手く、まさに少し魔法の様に扱う。Gitは複雑なマージを扱うことにかけて、非常に高い評価を得ている。非常にそうなので、マージのテキストの問題は彼らが以前に使用していた頃より遥かに優れている - 確かに私はこの記事の目的の為にテキストのコンフリクトを割り引いて考えさえする。

私がさらに心配する問題はセマンティックコンフリクトである。これのシンプルな例はプラム教授がグリーン牧師のコードの呼び出しメソッドの名前を変更する場合である。リファクタリングツールは安全にメソッドの名前を変更出来るが、それはあなたのコード上のみにおいてである。G1-6がfooを呼ぶ新しいコードを含む場合、プラム教授は彼のコード上ではfooを使うことが出来ない。あなたはそれを大きいマージの際に見つけるだけである。

ファンクションのリネームはセマンティックコンフリクトの比較的明白なケースである。実際問題として、それらは遥かに捕らえ難い。テストはそれらを発見する鍵となるが、そこにはより多くのコードがあり、マージする程、コンフリクトや問題を解決するのをより難しくさせる。コンフリクトのリスク、特にセマンティックコンフリクトはマージを大きく恐ろしいものにする。

大きなマージのこの恐怖はまた、リファクタリングへの抑止力として機能するコードをクリーンな状態に保つには絶え間ない努力である。上手にそれをする為には、どこであろうとも常に粗悪なコードが組み込まれない様に眼を光らせている必要がある。しかしながら、フィーチャーブランチ上のこのある種のリファクタリングは“巨大な恐ろしいマージ”をより悪くするので、厄介である。私たちが見る結果はフィーチャーブランチを使用するチームをリファクタリングすることに尻込みし、より汚いコードベースへと向かう。

確かに、私はこれをフィーチャーブランチが良くないアイデアである決定的な理由であると見做している。かつて、チームは終わりの見えないスパイラルにある自分たちのコードをクリーンな状態に保つ為のリファクタリングを恐れていた。

継続的インテグレーション

それらは、継続的インテグレーションによって解決する為に設計されている問題だ。継続的インテグレーションを行うと私のダイアグラムは次の様になる。

ここには先程よりもマージが沢山あるが、マージはより頻繁にすることでより容易になり、より小さく、そして、かえって大きな稀になっている。その結果、プラム教授はグリーン牧師が依存している幾つかのコードを変更しても、グリーン牧師は P1-2 でマージする際などより容易に見つけることが出来る様になる。この時点で、グリーン牧師は G1-6 ではなく、 G1-2 の変更を修正するだけである。

CIは大きなマージの問題を取り除くのに有効だが、それはまた、極めて重要なコミュニケーションメカニズムでもある。このシナリオでは、プラム教授が G1 をマージし、グリーン牧師が積極的にプラム教授のライブラリ上に構築していることに気がついた時、潜在的なコンフリクトが実際に現れる。この時点で、プラム教授はグリーン牧師の元に向かい、彼らの2つのフィーチャーがどう相互作用するかについて議論することが出来る。もしかしたらプラム教授のフィーチャーはグリーン牧師の変更とかみ合わない幾つかの変更を必要としているかもしれない。それら両方のフィーチャーを見ることによって彼らは双方の作業の流れに影響するより良いデザインを考え出すことが出来る。分離したフィーチャーブランチで作業をする開発者たちは遅くまで、おそらく対応するには遅過ぎるまで、これを見つけることが出来ない。コミュニケーションはソフトウェア開発における重要な要因の1つであり、CIの最も重要なフィーチャーの1つは人のコミュニケーションをファシリテートすることである。

この様なフィーチャーブランチはCIとは異なるアプローチで、大体の場合、重要である。CIの原則の1つは誰もが毎日メインラインにコミットすることである。それで、フィーチャーブランチが1日と続かないなら、フィーチャーブランチの実行はCIとは異なる生き物になる。私はかつて、人々が全てのコミットを全てのブランチに行い、おそらくCIサーバを使用して、自分たちでビルドを実行しているので、CIをしていると言うのを聞いたことがある。それは継続的ビルドであり、そして、望ましいことではあるが、インテグレーションが全くないので、それはCIではない。

無差別なインテグレーション

以前の私は挿話として、フィーチャーブランチを行う他の方法があると言った。プラム教授とグリーン牧師は早いサイクルで一緒に紅茶を飲むと言う。チャットしている間、彼らは相互作用するフィーチャーに取り組んでいるのを発見する。この時点で、以下の様に彼らは統合することを選択することも出来る。

このアプローチでは彼らは従来通り、終了時にメインラインにプッシュするだけである。しかし、彼らはお互いに頻繁にマージするので、これは“巨大な恐ろしいマージ”を避けることが出来る。つまり、私が言いたいのは、分離したフィーチャーブランチ計画の第一の問題はその分離にあるということだ。あなたがフィーチャーブランチを分離する時、そこにはあなたが認識していない成長している厄介なコンフリクトのリスクがある。その後、分離は空想であり、遅かれ早かれ、酷く打ち砕かれるだろう。

これはCIの形態のよりアドホックインテグレーションやそれとも全く異なる動物だろうか?私はそれが別の動物であり、CIの重要なポイントは誰もが日々メインラインに統合するということだと考えている。フィーチャーブランチを超えての統合は無差別なインテグレーション(PC)と呼んでおり、メインラインに関わりなく、必要としてさえいない。私はこの違いが重要であると考えている。

私は主に各コミット毎にリリース候補版を生み出しているとCIを見做している。
CIシステムとデプロイプロセスの役割はリリース候補版の生産準備を反証することである。
このモデルは最新の状態が共有されている幾つかのメインラインの完全なイメージの持つ必要性に依存している。

    • デイブ・ファーリー(Dave Farley)

無差別なインテグレーション vs 継続的インテグレーション

それが違うのであれば、PIはCIより良い、またはより現実的にどのような状況ではPIはCIよりも良いだろうか?

CIを行うと、あなたはVCSを使って“さくらんぼ狩り”を行う能力を失う。全ての開発者はメインラインに触れているので、全てのフィーチャーがメインライン上で成長していく。CIを行うと、メインラインは常に健全なので、理論的には(多くの場合、実際的には)あなたはどんなコミットの後でも安全にリリースすることが出来る。ビルド中のフィーチャーやまだリリース出来ないフィーチャーを抱えていても他のソフトウェアの機能性に損傷を与えることはないが、それがユーザインターフェースに表示されたくないならば、幾つかのマスキングが必要であるかもしれない。
これはフィーチャーのトリガとする為にはUI(ユーザインターフェース)にメニュー項目を含めないのと同じ位簡単である。

PIはここに幾つかの妥協点を提供することが出来る。それはグリーン牧師がプラム教授の変更を組み込む際に選択を許容する。プラム教授はP2で幾つかのAPIのコアを変更を行う場合、グリーン牧師はP1-2をインポートすることが出来るが、プラム教授のフィーチャーがリリースされるまで他のフィーチャーをリリースするが出来る。

この選別と選択の心配事の一つはPIが誰が彼らのブランチで何を持つかに関する経過を追うことを本当に難しくさせてしまうということである。実際には、ツールがこの問題を殆ど解決する様に思える。DVCSは変更とその起源に関する経過を明確に追え、プラム教授がG3をプルする際に彼が既にG2をプルしており、B2をプルしていないことを把握することも出来る。私は手でダイアグラムを描きミスをした可能性があるが、ツールはよくこれらの事柄の経過を追っている。

しかしながら、全体的に見ると私はVCS上で“さくらんぼ狩り”をすることを良いアイデアとは思わない。

フィーチャーブランチは経済的なモジュール方式である。フィーチャーブランチは手動マージによってシステムをビルドする代わりにこのメカニズムのソースコントロールによって、実行時間/デプロイ時間にフィーチャーの交換が容易な能力を提供する。

    • ダン・ボダート(Dan Bodart)

私は設定を変更することでフィーチャーを容易に有効化、または無効化する様な方法でソフトウェアを設計するのを非常に好む。ここにフィーチャートグル(FeatureToggles)と抽象化ブランチ(BranchByAbstraction)という2つの有用なテクニックがある。これらは、モジュール化とどの様に差異を制御する為に必要なものについて幾つかの考えを入れる必要があるが、私たちは結果がVCSに依存することがはるかに厄介であることが分かった。

PIについて私が気になる主なものは人とのコミュニケーションへの影響だ。CIを伴うメインラインはコミュニケーションポイントの役割を果たす。プラム教授とグリーン牧師が決して話さなくても、彼らは発生しようとしているコンフリクトを発見するだろう、それが形成された日の内に。PIを伴う彼らはコードを相互作用させるのに取り組んでいることに気づかなければならない。最新のメインラインはまた誰かが彼らが他の皆と統合していることを確信することを容易にし、彼らは誰が何をしているのか見つける為に詮索する必要がない、その為、後の統合まで隠される幾つかの変更がとても少なくなる。

PIはオープンソースから生じた。そして、オープンソースのそれ程強くないテンポがこの要因であるかもしれない。
一方、フルタイムの仕事ではあなたは1日の内、数時間プロジェクトに取り組むことになる。
この場合、優先順位に従って必要なフィーチャーを実装する方がより容易になる。
オープンソースプロジェクトに携わる人々はしばしば1時間だけ費やし、そして数日後に次の1時間を費やすといったことをしている。
フィーチャーは完成するまでに1人の開発者はかなり時間がかかるかもしれないし、より多くの時間を持っている他の開発者たちはフィーチャーをリリース出来る状態により早く出来るかもしれない。
この様な状況では、“さくらんぼ狩り”はより重要になることがある。

あなたが使用するツールが統合戦略の大部分からは独立していると認識することは重要だ。多くの人々がフィーチャーブランチとDVCSを関連付けるが、それは彼らがCIと共に使用するからだ。必要は作業はメインラインとして1つのリポジトリ上に1つのブランチをマークを付けるだけである。皆が毎日プルとプッシュした場合、その後、あなたはCIのメインラインを持っている。確かに規律のあるチームでは私は通常中央集中型のものよりもCIプロジェクトでDVCSを使用することを好む。規律のあまりないチームでは私はDVCSが長期間生存するブランチへと仕向けるのではないかと不安になり、中央集中型VCS不本意ながらブランチでチームを頻繁にメインラインにコミットする様に仕向ける。ポール・ハーマント(Paul Hammant)は正しいかもしれない:"私は“チームが分散型に移行する前に、チームはトランクベースの開発に熟練してはならない。”ということを不思議に思う。"