Git
git-flow
vcs
バージョン管理

git運用フローの選び方

会社のブログに書こうかと思ったけれど、ちゃんと調べられてないのでメモがてらQiitaに書いておく。

本稿ではチーム開発においてフローを選ぶ際のポイントについて述べる。

TL;DR

運用フローは次のポイントに注意して選ぶと良い。

  1. リリースサイクルの長短(長く計画的 or 短くアドホック)
  2. メンテするバージョンの数(1つ or 多数)
  3. 並行して開発するバージョンの数(1つ or 複数)
フロー リリース メンテ 開発
github-flow 1つ 複数
git-flow 1つ 1つ
stable trunk 中〜長 1つ 複数
mainline 中〜長 複数 1つ

git運用フローとは

VCS一般には「ブランチ戦略」とも言われる。
ここでは以下のように定義する。

git(VCS)を使う上で、どのブランチで作業し、
どのタイミングでブランチを分け、マージするかを定めたルールのこと。

よく知られているフローの例

// 安定trunkパターンとメインラインモデルについてよい解説をしている記事が見つからなかった。

選ぶ前に

一般に、「ソフトウェア」と一口に言ってもwebアプリ、モバイルアプリ、ライブラリなど様々な形態があり、形態によっても、またチームや組織によっても異なる制約が存在する。
フローはこの制約に沿ったものでなければならない。
自分の置かれた環境の制約をよく考慮し、次のポイントを確認してほしい。

判断のポイント

リリースサイクルの長短

サイクルが長いか、短いかを考える。これにはリリース作業の「重さ」の影響が大きい。
リリースに手作業が多かったり、テストが自動化されていないなど作業負担が大きい(=リリース作業が重たい)場合、リリースの回数を少なく抑えようとする動機が働くため、サイクルは長く大きくなる。
逆に自動化されたフローやテストにより気軽にリリースできる(=リリース作業が軽い)と、サイクルは短く小さくなり、回数も増えていく。

作業の重さの他に、受託の場合は顧客の都合であるとか、ソフトウェアの実行環境(例:GWとお盆と年末しかシステムを止められない等)にも影響を受ける。

サイクルが長い場合、リリースを始め開発プロセス全体がより計画的なものになっていく傾向がある。

長短に明確な基準はないが、ここではアジャイル開発で一般的なイテレーションの単位=2週間に1度のリリースを「中」とする。

  短                        中                   長

n/day < 1/day < 1/week < 1/2week < 1/month < 1/n month

メンテするバージョンの数

安定版としてユーザーに提供し、メンテナンスしていくバージョンの数を考える。
クローズドソースなwebアプリケーションでは通常1つ=本番となる。
ライブラリやユーザーに頒布するアプリケーションは複数のバージョンをサポートすることがあるだろう。

並行して開発するバージョンの数

常に次のリリースに向けての作業だけしている場合は開発バージョン(開発ライン)は1つ。
複数のマイルストーンがあり、その作業を同時並行で行なっている場合は開発バージョンが複数あるとする。

パターン別おすすめ運用フロー

リリースバージョンが1つ、サイクルが短い

github-flowがおすすめ。
短いサイクルで小さなリリースが可能な場合、「無関係なフィーチャーを統合して1回のリリースで出す」ことの必要がない。
大きなフィーチャーも小さなフィーチャーも同じように扱うことができる。
また大きなフィーチャーを複数人で担当する場合も、作業者ごとのブランチ+統合ブランチに分けることで容易に分割・統合できる。

リリースバージョンが1つ、開発バージョンが1つ、サイクルが中くらい

git-flowがおすすめ。
複数のフィーチャーをdevelop -> releaseにマージして1つにする点がポイント。
これによってリリースの回数を抑えることができる。
欠点としては開発ラインがdevelop1つしかないため、複数のマイルストーンで開発が走るようになると破綻する。
後述の安定trunkパターンを参照。

リリースバージョンが1つ、開発バージョンが複数、サイクルが中〜長

安定trunkパターンがおすすめ。
masterを本番相当とし、masterからマイルストーンごとに統合ブランチ(develop相当)を切る。
統合ブランチからフィーチャーブランチを作成し、作業が完了したら統合ブランチにマージする。
リリースの際は対象のマイルストーンの統合ブランチをmasterにマージする。
これは古典的ながら非常にシンプルで分かりやすく、git-flowと比べ次の点で優れる。

  • developreleaseが1つになっており、無駄なブランチを作らずに済む。
  • 緊急のマイルストーンが発生したと考えることでhotfixも他と同様のフローで扱える。

欠点は次の通り。

  • リリースサイクルが短くなるにつれマイルストーン=統合ブランチが増えるので煩雑になる。
    • この場合は前述のgithub-flowに寄せることをおすすめする。
  • 他のマイルストーンの開発がmasterにマージされたら、開発中の統合ブランチにバックマージする必要がある。

ブランチ命名規則の例

パターン 統合ブランチ フィーチャーブランチ
リリース日 20180401 20180401_awesome_feature
マイルストーン名 r2018_q1/head r2018_q1/awesome_feature

日付にするとリリース日がずれた場合にブランチ名とリリースが一致しなくなるデメリットがある。
逆に絶対リリース日を守るという強い意志を持ちたい場合におすすめ。

リリースバージョンが複数、開発バージョンが1つ

メインラインモデルがおすすめ。
masterをアクティブな開発ラインとし、あるバージョンをリリースした時点でブランチを切る。
各バージョンに対するメンテナンスはリリースブランチで行い、必要に応じてcherry-pickなどでバックポートする。

リリースバージョンが複数、開発バージョンが複数

webアプリ等において、普段のリリースバージョンは1つだが、UI変更を伴うβ版を提供するなどの理由で一時的にリリースバージョンが2つに増える場合がある。

この場合はメインラインモデルに切り替えるのではなく、git-flow等もとの運用フローをベースとして、masterから一時的なリリースバージョンのブランチを派生させるのがよい。開発ラインとする統合ブランチも合わせて作成する。
複数のリリースバージョン間でのバックポートを忘れないよう注意すること。

これは非常に労力がかかり大変なので、リリース複数x開発複数という体制はあまり長続きしないと個人的には思う。

まとめ

開発のポイントを踏まえたgit運用フローの選び方を説明した。
ケース別のおすすめフローは以下の通りである。

フロー リリース メンテ 開発
github-flow 1つ 複数
git-flow 1つ 1つ
stable trunk 中〜長 1つ 複数
mainline 中〜長 複数 1つ

この判断を誤ると、フローに合わせるために無駄なブランチを作ったり、複数バージョンの管理が難しくなったりする。
特にデファクトだからとgit-flowを導入しているケースは注意が必要で、実際の開発フローとgit運用フローが乖離していることがある。
オリジナルのフローを作りたくなった場合は、一度ここに書いたことを検討してみてほしい。

自分が安定trunkでいいんじゃないと思う例:

以上