無駄のないブランチ: マージとブランチの簡素化

Nicola Paolucci
Nicola Paolucci
リストに戻る

ブランチング ワークフローは、最小限の簡単なものから、複雑なもの、強固なもの、防御的なものまで、さまざまなタイプがあります。自分の組織に必要な複雑さとセーフガードのレベルはどの程度でしょうか。この投稿では、迅速性と堅牢性の間の妥協点について取り上げ、あわせて Git の活用の仕方を選択するためのガイドラインとアトラシアン内で習得した知識を提供します。

この記事のねらいは、自分のチームに最も効果的なブランチング モデルをどのように選ぶか、その選ぶ決め手となる識見とツールを提供することにあります。

指針となる考え方

  • マージを信頼する
  • 極端なブランチング モデルを避ける。
  • 可能であれば、ブランチの階層を単純化し、フラット化する
  • 開発プロセスツールがブランチング モデルの決定にどのような影響を与えるかを検討する

マージを信頼する

最適なブランチング モデルを選択するための第一歩は、マージを信頼することです。これは私が git; を最近採用したばかりのチームに向けて言っていることです。みなさんが既にこの段階を過ぎて、merge を活用している場合は、この項をとばして、次に進んでください。

古いシステムでは、どんな犠牲を払ってもマージを避けたり、マージ地獄に対処するために特別なチームを雇ったりするなど、極端な措置を講じざるを得ないことがありましたが、マージは git ではたいしたことではないことが判明しました。これは、いくつかの重要なことが原因です。

  • ブランチは非常に手軽で速いため、git では、ブランチを短期間使用して、すばやく統合することを推奨しています。
  • git では、マージがローカルで行われるため、マージの結果はふつう即時に反映されます。
  • git はブランチの祖先を把握していて、ワークツリー平面全体ではなく、関連のあるコミットのみマージします。このため、一般的にコンフリクトが少なくなります。
  • 自由に使えるマージ戦略はたくさんあります。このため、あなたはマージが大好きになり、裏を返してブランチングも好きになります。ブランチングとマージが非常に簡単になったため、一部のチームは、やり過ぎる、という反対の問題に直面しています。したがって、何事もそうですが、バランスを保ち、無理をしないことが肝要です。

極端なブランチングを避ける

Git の出現前と後の大規模なブランチ モデルを全体として眺めると、単純なものから階層化されたものへと変化するスペクトル上に位置していることがわかります。極端なモデルは問題を生じる可能性があります。さまざまなブランチング モデルから 2、3 取り上げて、望ましい点、望ましくない点を紹介しましょう。

単一ブランチの極端

Subversion の頃の記憶 : すべてを統制する 1 つのブランチ。長年、ソフトウェア チームは (私を含めて) 晴れの日も雨の日も、1 つのブランチ、trunk 上で、未完了のフィーチャーをもとにフィーチャーを完了させ、動作するビルドも障害のあるビルドも一緒にして、作業をしてきました。このプロセスは以前はよく機能したもので、今も機能しています。しかし、もう最も効率的なプロセスとは言えません。

悪口を言いたくなるが、気に入ってもいて、ともに育ち、今も使っている人がいる、単一ブランチの世界とは、このような感じです。

trunk

Git を採用して間もないチームや自分たちのワークフローを維持しようとするチームは、これと同じ感覚をもう一度作りだそうとしているのかもしれません。現在、git の用語では trunkmain と呼ばれますが、git で単一ブランチを使った作業ができます。以下のような具合です。

rebase-on-feature

誰もが main で作業し、誰もブランチでは作業せず、どの開発者も rebase を使って最新の変更情報を取り込みます。これは trunk のみを使う、昔ながらの Subversion のブランチング モデルにとても近いやり方です。

現代のチームがある程度の分岐を受け入れながらも、古きを愛するがゆえに、履歴を平坦化し、main がまさに上の図とまったく同じように見えるようにコミットのスカッシュ ルールを強制する話を聞くのは珍しいことではありません。

この際、何が失われているのでしょうか?コンテキストとトレーサビリティです。詳細については、マージとリベースの議論に関する私の記事を読んでください。

単一ブランチの主な欠点とは何でしょうか。main が壊れると、全員の作業が中断します。git では、開発者がプロジェクト全体の履歴を自由に利用できるというのは、そのとおりです。遅れを生じることなく、破損が発生する前の時点に戻り、問題が解決されるまで作業を続けるのは簡単なことです。しかし、開発者がこのタイム トラベルを苦もなく実行する方法を知っている場合、自分の作業の仮置き場としてローカル ブランチを使っているのも事実です。

統合ブランチの階層が多すぎる

反対側の極に位置するのが、プロセスを過剰なほど形式化し、環境を簡素化する代わりに複雑化するようなやり方でプランチを活用しようとする組織です。

たとえば、次のブランチング モデルをご覧ください。

多すぎるブランチ

この例では、チームはユーザー ストーリーごとにブランチを作成し、次いでそれぞれのユーザー ストーリーから課題ごとのブランチを作成し、それぞれの課題ブランチからサブタスクごとのブランチを作成しています。そして、すべてのブランチは main に行き着くまで、next ブランチに順番にリリースされていきます。

これは前に言いましたが、本当のことです。git では、ブランチとマージは簡単にできますが、プロセスを複雑にすると、その簡単さにも関わらず、チームのベロシティに影響が出ます。

可能であれば、ブランチの階層を単純化し、フラット化する

少なくとも今、私たちは極端な事態を避けるべきだとわかっています。それでは、構造と柔軟性の良い妥協点は何でしょうか?いくつかの重要な質問に答えることで、チームの理想的な場所を簡単に特定できます。

  • プロジェクトをサポートするために最小限必要な、長時間稼働するブランチの数はいくつですか?
  • 自分はソフトウェアの古いバージョンを保持する必要があるかどうか。一般的に言って、テストスイートの強度、チームに寄せる信頼と責任のレベル、製品の課題に対する許容度などと矛盾が生じない範囲で、ブランチ階層を可能な限りフラット化するように努めるべきです。

アトラシアンでは、BTF (ファイアウォールの内側) 製品とオンデマンド サービス (クラウド) の両方で、比較的フラットなブランチング モデルをいくつかのチームで使用しています。

ユーザー ストーリーごとに 1 つのブランチ、または課題ごとに 1 つのブランチ (Jira 課題) ですか?

ブランチの粒度は重要です。あまりにも粗く、多くの人が一緒に作業することを余儀なくされると、前に強調した単一ブランチの問題に遭遇します。ブランチを作成 (および公開) しすぎると、レビュー プロセスと全体像が混乱し、肥大化する可能性があります。

ブランチのスコープを選択する上で優れた粒度は、"課題ごとに 1 つのブランチ" であることがわかりました。

健全なワークフローその 1: 単一の安定した main、ブランチを活用するが、シンプルに保つ

私が最近書いた シンプルな git ワークフロー という記事で、継続的デリバリーに適したシンプルなブランチング モデルを紹介しました。その記事は main は本番ブランチであるという考え方を中心に取り上げています。main に対するすべてのコミットはタグ付けされた本番リリースです。このワークフローは、たとえば、ウェブ アプリケーションやストア フロント、Saas など、一般的に過去の古いバージョンを保持する必要がない状況に適した優れたワークフローです。

Sane ワークフローその 2: シンプルにするが、古いリリースを維持する

製品の古いバージョンを保持する必要がある場合は、安定した main が 1 つあるだけでは十分ではありません。解決策は、チームがサポートする必要があるバージョンごとに長期間稼働するリリース ブランチを用意することです。変更が反映される向きは、常に古いブランチからより新しいブランチに向かい、決して反対の方向には向かいません。理由については、ブランチ ベースのワークフローの本質と題したプログ投稿を参照してください。

長い期間稼働しているリリース ブランチ

必要が生じた時に作成する追加の統合ブランチ

そうする必要がある理由を正確に理解している場合は、少人数の開発者からなるチームの作業を、1 イテレーション以上の間、他と分離しておくことが有効です。これを実現するのに、統合ブランチをセット アップする方法があります。このブランチは、最終マージを簡略化するため、可能な限り頻繁に main からの最新情報で更新する必要があります。

たとえば、Bitbucket Server チーム内では、リリース サイクル (この場合は約 6 週間) ごとに 1 - 2 回、追加の統合ブランチが発生します。これらは、チームに複数の作業ストリームがあり、少しの間隔離する必要がある場合に必要です。

開発プロセスとツールはブランチング モデルに影響を与える

チームの開発プロセスとツールは、ブランチング モデルの決定と、チームの俊敏性と有効性に大きな影響を与えます。

Bitbucket Server または Bitbucket Cloud のプル リクエスト機能を使用すると、ブランチを 1 つのコミットに押しつぶすことなく、同僚の作業を直接レビューできます。

そして、チームのステータスと成果物を的確に把握できるようになればなるほど、チームの全員が並行して作業を進められるよう、自由な割り振りができるようになります。

特定のフィーチャーのビルドやプルリクエスト、ブランチ、コミットなど、すべてのステータスを、一目で把握できたらと想像してみてください。素晴らしいお知らせですが、このようなユートピアはすでにここに実現しているのです。この見事さをご覧ください。

JIRA 開発パネル

*この開発パネルは Jira 6.2、Bitbucket Server 2.10 以降、Bamboo 5.4 で利用できます。

上に表示されているのは、Jira の新しい「開発」パネルです。Bitbucket および Bamboo と組み合わせると、1 つの場所で開発のあらゆる更新情報が得られます。このパネルはすべての Jira 課題およびラピッド ボードで利用可能であり、これを使用すれば、開発サイクル内の全員が情報を共有できます。これからは情報を求めて調べまわる必要は一切なく、ブランチのステータスを完全に把握し、ビルドに障害があるブランチを特定し、デプロイをモニターできます。コードを追跡する代わりに、すばらしいコードをビルドし、リリースすることに時間を費やしてください。

結論

この記事は予想よりも長くなりましたが、チームにとって効果的で無駄のないブランチング モデルを選択する方法に関する優れたガイドラインとなることを願っています。DVCS を使いこなす方法について詳しくは、@durdn で私、または @Bitbucket チームをフォローしてください。

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

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

今すぐ始める