Git か SVN か? Nuance Healthcare はどのようにして Git のブランチ モデルを選んだか

Matt Shelton
Matt Shelton
リストに戻る

これは Nuance Healthcare 社の Matt Shelton 氏からのゲスト投稿です。この投稿は、Subversion から Git に移行した彼のチームの話をまとめたシリーズの第 1 回目で、移行した理由や移行の過程で経験した事柄が語られています。Matt は Atlassian Summit 2015 でも、このテーマについて話をしています。このシリーズでは、彼の持ち時間の 30 分では話せなかったことをすべて取り上げ、その時の話とは違った側面についても話をします。

背景

私のチームは、Nuance のヘルスケア部門に所属しています。チームは、米国の東海岸にあるいくつかのオフィスと自宅、プネーのオフィスに、地理的に分散しています。私たちは、NLP[1] ソリューションをヘルスケア市場に提供するために Java Web サービスを開発しています。

私たちのサービス購入者は、たいていの場合、EHR ベンダーなど、他の健康管理ソフトウェア会社 (当社を含め) や健康分析会社です。私たちは直接病院に商品を販売し、アプリケーションを使用する医師から医療請求担当者まで、さまざまな個人ユーザーにも直接販売しています。私たちのような "普通の" 人は、私のチームが作るソフトウェアを使用することは決してありません。

私たちのチームは、アプリケーション ライフサイクル管理製品の組み合わせを使用して何度も経験を積んでいます。私たちは、Rally Enterprise と Seapine TestTrack Pro を組み合わせて事業を開始し、Rational Team Concert とともに約 14 か月間にわたって努力を重ね、最終的には Atlassian Stack (JiraConfluenceBambooCrucibleBitbucket) に完全に移行しました。私たちは歴史的に、Subversion 1.4/1.5 と SCM とともに準通常のトランク/ブランチ/タグ構造を使用していました。ビルド プロジェクトと依存関係を管理するために maven をずっと使用していましたが、Jira とその柔軟なビルドとデプロイ エージェント機能とのより緊密なインテグレーションを利用するために、少し前に Jenkins から継続的インテグレーション (CI) 用の Bamboo に切り替えました。(現在) 使用しているものはすべて、いくつかの理由により、ファイアウォールの内側にあります [2]。

Git か SVN か

4 つの製品ファミリーにわたって約 10 個の個別製品をサポートしており、これらの製品の所有者は常に優先順位付けとタイミングに苦慮しています。私たちの仕事に対する需要が高まっているのはすばらしいことであり、これは決して不満ではありませんが、奇妙なタイミングで製品をリリースしたり、スプリントの途中で方向を変えたりすることも必要になります [3]。

私たちの開発プロセスには、時々もうこれ以上無理と感じさせる時がありました。私のチームで日常的に交わされていた会話は、次のような感じです。

: 顧客 foo が来週ベータ版に移行できるように、リグレッション テストのためにリリース 1.8.0 を QA にリリースする必要があります。開発者: 私はまだ、トランク内の ABC-123 に取り組んでいます。これはまだ終わっていません。: foo は ABC-123 を必要としていません。ABC-123 は次のリリースに入れることができます。開発者: しかし、私はこれに何週間も取り組んできました。製品をリリースするために分岐する明確なポイントがありません。: では、あなたはすべての変更を手作業で元に戻す必要があります。あなたに残された時間は約 2 時間しかありません。そうでないと、QA が間に合いません。

もちろん、私が嫌な奴のように思われることは重々承知しています。私にはそうするつもりは一切ありませんでしたし、強調するために少し誇張していることも事実です。しかし、私たちは本当に、製品をリリースするために、ある場所にあるコードをその場所から一時的に取り除いてから、次のリリースのためにそのコードを元に戻す方法を理解しなければならなかったのです [4]。そして、こんなことが日常茶飯事でした。

さて、私は皆さんの一部が「Subversion がブランチをサポートしていますよね、Matt...」と考えていることを承知しています。それは間違いありません。そして、私たちは場合によっては SVN 1.4 と 1.5 で時々それらを使用していました。SVN ではブランチングは細かい作業であり、マージにはうんざりすることがあります。SVN が成熟するにつれて、SVN は良くなっていることも確かです。しかし、そこには私たちにとってもっと良い選択肢があることがわかっていたので、SCN や Git に関する問題が生じたとき、私たちは Git を手に入れることに着手しました。

メモ: 最新の SVN (当時は 1.8) を調べて、私たちが抱える問題を解決するに足るほど強力な機能があるか確認しましたが、何となく物足りなさを感じました。社内のグループの 1 つは大規模な Perforce システムをセットアップしていて、私たちに必要なものを数多く備えていましたが、私は単純にライセンス コストに我慢できませんでした。また、少しの間 Mercurial を検討しましたが、結局は、それまでチームが Git を扱った経験から Git を採用するのが正しい選択だということが十分わかりました。

私は、アトラシアンのツールは git を使用するチームに対して実際に有利に機能するという事実を隠し立てすることはしません。他の SCM は正常に動作します。私たちの SVN インテグレーションは、特定のユーザー ストーリーの変更が行われた場所に私たちをリンクしてくれた点において十分でした。ただし、Bitbucket Server [5] を代わりに使用するチームのインテグレーション機能は、Jira Software インターフェイスと開発エクスペリエンスにおいて、より強力でより自然に見えます。このことは、Bamboo も同様です。

このことがわかっており、サミット 2013 ですばらしいデモをいくつか見てきたので、私はチームに Git を選択するよう強く勧めました。誰も異議を唱えず、私たちには変更を加えるためのライセンスを既に入手していました。

Git ブランチ モデルの選択

この変更を行うことを決めた後、最初に直面した課題は、チームにどの Git ブランチ モデルを実装するかを決めることでした。アトラシアンの Git マイクロサイトサミット 2013 でのこのすばらしいプレゼンテーションでは、ブランチ モデルが何であるかをより詳細に説明しています。短いバージョンでは、Git でブランチを使用して開発ワークフローを強化する方法を説明しています。

SVN には、「必要なことがわかったときに作成する」と私が呼んでいるブランチのモデルがありました。

  • 最新のコードは trunk 内にあります。trunk からのリリースは A.B.0-{build} のようにナンバー付けされます。
  • トランクベースのリリースに修正が必要な場合 (たとえば、1.2.0-64 にバグがある場合)、ブランチが作成され、そこから A.B.C-{build} リリースがリリースされ、C の部分はリリースが出されるたびにインクリメントされます。このブランチは特定の A.B にはまったく存在しない場合があり、複数存在する場合もあります。
  • また、tags ディレクトリ内のすべてのリリースにもタグ付けします。

バージョンについての余談何年も前、私がちょうど開発チームを管理する経験を積んでいた頃、そのチームのリリース エンジニアがバージョンを設定するシステムを定めていましたが、それが、何と言えばいいのか、実に直感的ではないやり方でした。すべてのリリースは基本的に前回のリリース (A.B.n) のパッチで、パッチの作成元に対する配慮はありませんでした。元になっているものの所在や、ほとんどの場合がそうですが、リリース順を見つけるには、svn log を調べる必要がありました。私たちは参照用に印刷したツリー図を壁に貼っていました。また、一般向けのリリース番号は 3.0、3.1、3.5、4.0 といったものであるか、または基本的に顧客が期待するようなものになりがちでした。いいですか、私のチームが制作していたのはパッケージ製品ではなく、ウェブサービスであったにも関わらずです。それは契約制作の API でした。数年前、私はチームのビルドの責任者になり、したがってリリースの責任者になりましたが、セマンティック バージョニングのルールを踏襲しようとしました。上部の経営陣の反対に耐えなければならないことが数回ありましたが、今ではルールがそのように定められている理由が理解されていて、決して過去を振り返ったりしていません。パートナーはそのような明確さを正しく評価してくれています。

あるリリース (たとえば、1.2.0 とします) に取り組んでいて、リリース日が近づいているときに、まだフィーチャーを開発中であるといった場合に生じる問題について、前にお話ししました。作業途中のコードを抜き出して、リリースし、branches/1.2.1 にブランチした後、そのコードをマージして元に戻す必要が生じ、その作業の間、誰のハードドライブもクラッシュしないように願っているというような話です [6]。

共有のトランクからあるフィーチャーだけを丸ごと取り除くのは面倒なことです。その作業をしなければならないときは、誰もがうんざりするものです。svn blame は強力な差分ツールとして役に立つことがありますが、それを使って作業するのは悩ましいものです。ツールが示す結果が自分への個人攻撃のように思うことがよくあり、私の計画のまずさのせいでリリースに間に合うようにきちんと準備が整えられなかったと感じていました [7]。私のチームは十分すぎるほど長い間、こうしたことに耐えてきました。

時には面倒を避けようとして修正しすぎたり、ただリリース前にトランクに汚染が及ばないようにするという理由で、2、3 日開発者に何もせずにいるように (言うなれば、仮想的なコード フリーズです) 頼もうとしたりしました。

そういう次第で、少なくともフィーチャー ブランチが必要なことはわかっていました。応用が可能なシンプルな Git ブランチモデルがあります。製品用の main ブランチと、あらゆるフィーチャーやバグ、その他の用途に使用するフィーチャー ブランチという構成です。main に送り出したものはリリース用に確実に送り出されるように、チームはマージ命令を管理する必要があります。これは、基本的に以前使用していたのと同じ構成で、フィーチャー ブランチの分離は進んでいますが、私たちが求めていたのはパワーを発揮できる自由でした。

私たちの環境では、本番環境でいくつかのバージョンを維持する必要がしばしばあり、たった今取り組んでいるリビジョンより 2、3 マイナーなリリース内の不具合を修正することが必要な場合もあります。そのため、フィーチャー ブランチに加えて、以前のリリースの問題を修正できるようなリリース ブランチなども必要でした。これは、Atlassian Bitbucket Server チームが行います。実行時間の長いサポート ブランチで修正を行い、それをブランチ ストリームにマージして、修正がすべてのサポート ストリームに反映されるようにします。

彼らのモデルは非常に見栄えが良く、私たちは、このモデルでプロトタイプのインタラクションをいくつか実行して、私たちのニーズに合っているかどうかを確認しました。彼らにとっての「キラー アプリ」は、開発ブランチまでの修正のローリング マージです。私たちはこのコンセプトを気に入っていましたが、試してみるたびに、Maven の依存関係に関して何らかの問題に遭遇しました。また、原則として、あるバージョンから別のバージョンに作業を直接マージしたいとは保証できませんでした。場合によっては、バージョン間で同じ修正を若干異なる方法で実装する必要があったため、直接マージは不可能でした。

チーム メンバーの何人かは、「Git-flow」と呼ばれるこのモデルのバリエーションを強く支持しました。Git-flow は、Vincent Driessen が作成したブランチの命名規則とマージ ガイドラインのセットです。これはチームにとって非常に自然な感じでした。「x を実行する必要があるときに何をすべきか」に関する質問の多くが排除されたので、私たちはこの構造を気に入っていました。答えは総じて非常に明白でした。Git-flow とは何かを説明するよりも、アトラシアンのチュートリアルで詳しく読むことができます。

git-flow に関して残された唯一のギャップは、本番環境で長時間実行されるこれらのリリースにどう取り組むかということでした。main は前進し続けているため、以前のリリースのバグ修正に Git-flow ホットフィックス ワークフローを使用できませんでした。一方、私たちは常にサポート ブランチを望んでいるわけではありませんでした。

たいていの場合、本番環境の最新のリリースにパッチを適用するためだけに使用するホットフィックスで十分で、サポート ブランチはもっと前に戻る必要がある場合や、何らかの理由で互換性を維持する必要がある場合にのみ使用しています。後者の使い方をする場合について、私たちはさらに分析を進め、ホットフィックス ブランチやマイナーバージョン アップグレードではなくサポート ブランチの使用を選択する場合の基準を考え出しました。

  1. コードを開発ブランチにマージして戻すのが簡単ではない場合。
  2. パートナー/顧客は、最新リリースに伴うインターフェイスの変更には対応できません。
  3. 変更できない内部の依存関係があります。[8]

どちらの Git-flow 拡張パッケージ [9] も、サポート ブランチのコンセプトをサポートしています。これは Git-flow の元のドラフトの一部ではありませんが、インクルージョンを保証するほど人気が高まっています。

Git-flow は、私たちが必要なツール サポートと、気に入ったワークフローを提供してくれました。次回の記事では、私たちが開発プロセスをするために使用した POC プロジェクトで実際に使用してみたときに何が起こったのかについて説明します。それは... 学習体験でした!

[1]: 自然言語処理。私たちは皆さんの考えていることがわかります。(実は、それほどでもありません。)

[2]: アトラシアンのクラウド サービスには魅力的な点がたくさんありますが、当面はサーバーとデータを秘密にしておく必要があります。PHI データについては個人的に行うことは多くなく、当社のソフトウェアが PHI データを処理してくれ、これをできるだけ安全に保つことが重要です。

[3]: シーッ... Ken Schwaber には内緒にしておいてください。

[4]: いずれにせよ、これはほんの数日だったかもしれません。

[5]: 以前は Stash と呼ばれていました。アトラシアンの秋のリブランディングです!

[6]: 前のコミットからいつでも取り出せたことはわかっています。冗談でした。

[7]: これはいつもそうであるわけではありません。通常は、他の誰かの時間枠が繰り上がり、私たちが迅速に対応しなければならないことが原因です。

[8]: これは、私自分のブログでは取り上げることができないことの 1 つです。信じてください。「理由」があります。

[9]: Vincent Driessen によるオリジナル パッケージはもう保守されていません。ただし、新しいフォークは定期的に更新されています。

Git を学習する準備はできていますか?

この対話式チュートリアルを利用しましょう。

今すぐ始める