実践反復型ソフトウェア開発を読む part2~マージの戦略
「実践 反復型ソフトウェア開発」のマージの概念は、Gitのコマンドをイメージしながら読めば、よく分かる。
ここでは、ポート(ブランチ間のマージ)の用語を抜き出してみる。
理解できたことをメモ書き。
【1】ポートの種類
「実践 反復型ソフトウェア開発」では、あるブランチにコミットしたチェンジセット(複数のソースの変更)を親子関係にあるブランチへ適用してコミットする操作をポートと呼んでいる。
似たような言葉として、ポーティング(移植)もある。
ポーティングは、製品の移植やWindowsの後方互換性のように、ある製品のソフトウェアを他の製品でも動作するように移植して修正・再構築する作業を指す。
ポーティングとは【porting】(移植) - 意味/解説/説明/定義 : IT用語辞典
ポートは2種類がある。単にマージの向き先が違うだけ。
・バックポート:サブブランチ→メインラインへのポート。
例えば、リリースブランチ上のセキュリティパッチやバグ修正のパッチをメインラインにも反映する場合、あるいは、製品の後方互換性維持のために、過去バージョンのI/Fに関わる修正パッチを最新バージョンの製品にも取り込む場合に使われる。
バックポートとは【backport】 - 意味/解説/説明/定義 : IT用語辞典
・フォワードポート:メインライン→サブブランチへのポート。
【2】複数のチェンジをポートしたい場合、下記の用語がある。
・バルクポート:範囲を指定して、複数のチェンジセットをまとめてポートする。
例えば、Gitならば、4abcae1から99daed2までのチェンジセットをマージしたい場合、
git cherry-pick 4abcae1..99daed2 のようなコマンドに相当するだろう。
あるいは、topicブランチの全チェンジセットをmasterへまとめてマージしたい場合。
git merge --squash topic のようなコマンドになるだろう。
・さくらんぼ摘みポート(cherry-pick port):必要なチェンジだけをポートする。
例えば、Gitならば、4abcae1と99daed2だけのチェンジセットをマージしたい場合、
git cherry-pick 4abcae1 99daed2 のようなコマンドに相当するだろう。
普通は、さくらんぼ摘みポートよりもバルクポートを利用した方が、追跡する手間が減る。
実際は、ユーザブランチやリリースブランチからメインラインへのポートはcherry-pick、機能ブランチなどの開発ブランチからメインラインへのポートはバルクポートを使う時が多いだろう。
【3】ベースラインとリベース
ベースライン:ビルドが一定の品質に達した時点のスナップショット(タグ)。
リベース:ブランチを作った後に、メインラインの新しいベースラインへ移動する操作。
リベースの本来の意味は、ベースラインを移動する操作のこと。
「実践 反復型ソフトウェア開発」のリベースの例として2つある。
一つ目は、バルクポート(FI)によるリベース。
メインラインから開発ブランチが派生した後、最初のベースライン(サブブランチが派生した時点)から次のベースラインまでにコミットされたメインラインのチェンジ全てを開発ブランチへバルクポートする場合。
「Gitのrebaseコマンド例1」に相当する。
このパターンは、開発ブランチへメインラインの最新の修正内容を同期させたい場合に相当するだろう。
作業対象となる開発ブランチを乗り換える必要もなく、開発ブランチ名も変わらないので、運用しやすい。
2つ目は、ブランチの切り直しによるリベース。
例えば、メインラインから、ユーザブランチ(あるユーザ専用の修正を製品に入れるためのブランチ)を切った後に、カスタマイズ前の古い製品がバージョンアップした時、古いカスタマイズ前の製品ブランチからユーザブランチへバルクポートする場合。
「Gitのrebaseコマンド例4」に相当する。
ユーザブランチに、カスタマイズのための修正パッチをマージできるので、運用しやすい。
他には、masterがSVNリポジトリのために、リベースを使ってコードラインを一直線にせざるを得ない場合もある。
「Gitのrebaseコマンド例2」に相当する。
例えば、masterからF1ブランチを派生させて、F1ブランチ上で新機能を開発していて、masterでも修正が発生していたとする。
その場合、最初にF1ブランチのベースラインをmasterの最新リビジョンへ変更させるようにリベースする。
次に、F1ブランチをmasterへFast-fowardマージでそのままマージすれば、F1ブランチのリビジョンがそのまま取り込まれて、masterは一直線になる。
git-svnを使う場合は、このパターンが多いはず。
git rebase F1 master
git checkout master
git merge F1
他には、孫ブランチを子ブランチと同じベースラインへ変更して、マージしやすくする場合もある。
「Gitのrebaseコマンド例3」に相当する。
リベースされた孫ブランチを親ブランチ(master)にFast-fowardマージすれば、masterを一直線にできる。
git --onto master F1 F2
【4】チェンジのプロモーション
チェンジセット:チェンジ(ソースの変更箇所)の集まり。
ペイロード(積み荷):チェンジセットの集まり。
バルクポートの対象となる指定した範囲のチェンジセットは、ペイロードである。
チェンジのプロモーションとは、あるブランチの修正(チェンジ)をより安定したブランチへポートすること。
ポートの向き先(バックポート、フォワードポート)によって、RIとFIがある。
【RI(Reverse Integration)】
バックポート(ブランチ→trunk)の方向へバルクポートする。
(1)コミットポリシー(ビルドエラーを起こさない etc)を適用する。
(2)定期的にRIテスト(CIやスモークテストに近い)を行う。
【FI(Foward Integration)】
フォワードポート(trunk→ブランチ)の方向へバルクポートする。
(1)更新ポリシー(ソースを最新化する etc)を適用し、trunkと頻繁に同期する。
2つのブランチ間でポートを繰り返すことを双方向マージ、はしごマージ、階段マージと呼ぶ。
双方向マージは、メインラインから派生した兄弟ブランチ、親子、子孫のブランチ間のポートを手作業ではなく、SCMツールで実施できなければ相当に面倒になる。
merge tracking機能が強いGitやMercurialなら、どのチェンジセットがポート済みで、いつ誰がポートしたのか、を覚えてくれるので簡単に操作できる。
SVNはVer1.5からmerge tracking機能をサポートしたが、おそらく使われていない機能ではないだろうか?
| 固定リンク
「ソフトウェア工学」カテゴリの記事
- アーキテクチャ設計はベストプラクティスを参照するプロセスに過ぎないのか?~Software Processes are Software, Too(ソフトウェアプロセスもまたソフトウェアである)(2024.09.22)
- 「システムアーキテクチャ構築の原理」の感想part2~非機能要件がシステムのアーキテクチャに影響を与える観点をプロセス化する(2024.05.06)
- 「システムアーキテクチャ構築の原理」の感想(2024.05.06)
- ソフトウェア工学の根本問題から最近のソフトウェア設計を考えてみる(2024.03.03)
- マイクロサービス設計は従来のアーキテクチャ設計と何が違うのか(2024.01.02)
「構成管理・Git」カテゴリの記事
- 「GitLabに学ぶ 世界最先端のリモート組織のつくりかた」の感想(2023.12.10)
- パッケージ設計の原則の意義は変化しているのか(2023.09.30)
- 小説活動にプルリクエスト駆動が必要になってきた(2022.05.08)
- 【資料公開】チケット駆動開発の解説~タスク管理からプロセス改善へ #redmine(2022.01.14)
- プログラミングしてる時はでっかいピタゴラ装置を作ってるみたいな感じ(2022.01.09)
「Agile」カテゴリの記事
- 「システムアーキテクチャ構築の原理」の感想part2~非機能要件がシステムのアーキテクチャに影響を与える観点をプロセス化する(2024.05.06)
- 「スクラムの拡張による組織づくり」のScrum@Scaleの感想(2024.03.31)
- ソフトウェア工学の根本問題から最近のソフトウェア設計を考えてみる(2024.03.03)
- 「GitLabに学ぶ 世界最先端のリモート組織のつくりかた」の感想(2023.12.10)
- 概念モデリングや設計原則は進化しているのか(2023.10.21)
コメント