git の一般的なワークフロー (git flow) では機能ブランチが使用され、新しい機能ごとに個別のブランチが作成されます。開発者は、これらの分離されたブランチに新しい機能を実装し、その変更をmain
ブランチまたはmaster
ブランチにマージして戻します。
このワークフローの利点は明らかです。別のブランチを QA 環境で簡単にデプロイしてテストでき、重大なバグが検出された場合でも、 main
ブランチにマージされません。同じブランチ内で問題を修正したり、コードを改善したりできます。
一方、メイン ブランチは常にデプロイ可能であり、その問題から保護されています。
残念ながら、この戦略にはマージ競合という重大な欠点があります。存続期間の長いブランチがある時点で避けられない場合、これらの競合を解決するのは非常に難しいため、ブランチを完全に削除して最初から開始する方が簡単になります。
また、競合が多い場合は、マージ結果が予測できない場合があります。
ただし、これが唯一の可能な戦略ではありません。この記事では、上記の欠点を回避して新しい製品機能を管理する別の方法について説明します。
Git の設計によれば、同じファイル行内のブランチに異なるコンテンツがある場合、マージ中にマージ競合が発生します。
これを説明するために、2 つのチームが同じサービスの更新を実装するシナリオを考えてみましょう。チーム A はクレジット カード サポートを統合し、チーム B はユーザー プロフィール ページを刷新しています。これらの機能は互いに何の関係もないようです。
しかし、支払い関連のコードは以前はプロフィール ページのコードと同じ場所にあったことが判明しました。そこで、両チームはコードを別々のブランチに抽出し、統合を書き直しました。
ここで問題は、誰が最初に変更をmain
ブランチにマージし、他のチームが結果として生じる競合を解決しようとしている間、問題が自分たちの側にないふりをするかということです。
マージ競合を完全に回避することは不可能ですが、次のよく知られたルールを使用すると、マージ競合を確実に解決しやすくすることができます。
アクションが難しくて怖い場合は、より頻繁に実行してください
Git の用語で言えば、これはできるだけ頻繁に (理想的にはコミットごとに) マージする必要があることを意味します。もちろん、その場合、競合がより頻繁に発生しますが、解決ははるかに簡単になります。
これはトランクベースの開発と呼ばれ、変更をmain
ブランチに直接プッシュし、不必要な場合はブランチの使用を避けることを意味します。
上の例では、両方のチームが定期的に変更をmain
ブランチにプッシュした場合、同じファイルを変更しようとしていることにすぐに気づきます。
さらに言えば、問題を完全に回避することもできたはずだ。 2 番目のチームは、最初のチームがファイルを変更した後で、それらの更新を考慮して変更を開始することになります。
注意深い読者は、「すべてが素晴らしく聞こえますが、テストはどうすればよいのでしょうか?」と疑問に思うかもしれません。機能ごとのブランチにより、リリース前に新機能全体を個別にテストできます。継続的に変更をmain
ブランチに統合すると、その可能性はなくなります。
機能フラグまたは機能切り替えは、実行時に特定の機能を切り替えることができる単純な動的フラグです。一般に、機能フラグを使用すると、QA エンジニア、スタッフ、特定の顧客などの特定のユーザー グループに対して機能を有効または無効にすることもできます。
機能フラグには、さらにいくつかの利点があります。
機能フラグを使用すると、 main
ブランチへの変更のプッシュがより安全になります。機能フラグがオフになっている間、変更は誰にも影響しません。
この手法により、 main
ブランチを直接操作したり、存続期間の短いブランチを作成したりすることができます。そのため、マージ競合は非常にまれになり、すぐに解決されます。
要約すると、機能フラグと組み合わせたトランクベースの開発は、機能ブランチでの変更の競合によって引き起こされる多くの問題を回避するのに役立つ優れた手法です。
ただし、いつものことですが、すべてに当てはまる万能の方法はありません。これは、同じリポジトリで作業している少数のチームで機能します。通常、この数を増やすにはいくつかの調整が必要です。
さらに、特定の状況やタスクに応じて、機能ブランチまたは機能フラグを使用するという両方の方法を常に使用できます。