2022年3月9日

DevOps

Git のリベースとマージ。いつ、どちらを使うべき?

Gitのリベース(git rebase)とマージ(git merge)は、いつどちらを使えばいいのか混乱することがあります。分かりやすくするため、それぞれの戦略が適切である事例を紹介します。

02.-Design_Blog-header-10-tablet.webp

私たちの多くはGitに慣れ親しんでいて、開発者がコピーやブランチを行うなどの概念も理解しています。この記事では、Gitのリベースとマージの違いと、さまざまなシナリオに対する最適な戦略を紹介します。最近のリリースプロセスの強化やブランチ戦略の実装では、リベースを使いました。その理由も説明します。

Git mergeの例

mergeを説明するために、ターミナルからいくつかのコマンドを実行しました。次に、それらの図を追加して、マージで何が起こっているかを説明します。


image-21-1920w.webp

上の画像では、new_branchを作成して2つのコミットを追加し、Git logを表示させています。

image-22-1536x437-1920w.webp

この図では、masterとnew_branchがどのように乖離しているかを明確にするために、Gitログのグラフを表示させました。

image-23-1536x471-1920w.webp

次のセクションでは、masterに戻ってコミットを作成し、再帰的なGitマージ戦略でmasterブランチをnew_branchにマージしています。

image-24-1920w.webp

さて、Gitのログを調査してみると、new_branchに別の新しいコミットが追加されています。これは、マージのために生成されたものです。

image-25-1536x769-1920w.webp

最後にGitのログを見ると、コミットグラフにこのように表示されます。

image-26-1536x289-1920w.webp

上記のオプションから、マージは非破壊的な操作であり有用なことが明らかになります。唯一の欠点は、余分なMerge commitが作成されることでコミット履歴をたどる際に邪魔になる可能性があります。

デメリット:masterがアクティブすぎる場合にこの戦略に従うと、Merge commitが増えすぎて、多くの場合履歴が汚くなってしまいます。

image-20-1920w.png

Git rebaseの例

同じ例で、リベースについて考え直してみましょう。この戦略では、機能ブランチの先端全体を移動させます。さらに、この方法ではmasterブランチにある新しいコミット全部を効率よく導入できます。しかし、リベースはマージコミットとは違い、元のブランチの各コミットに対して新しいコミットを作成し、プロジェクトの履歴を書き直します。

 

image-19-1920w.png

メリット:リベースすることで、ブランチ履歴をよりきれいに保つことができます。さらに、余計なマージコミットを発生させないようにすることもできます。最後に、上の図から、ブランチ履歴をリニアに保つのに役立つことが分かります。

対話型リベース:これはリベースに関する重要な機能で、開発者が自分の機能ブランチに入れたいコミットを選択できるようにするものです。たとえば、私は自分の機能ブランチでFeature-Xの開発をしていますが、あるコミットはFeature-Xに影響を与えるmasterブランチに入りました。master/mainブランチには、他の機能やバグ修正のためのコミットも複数入っているかもしれません。そこで登場するのが対話型リベースです。必要なコミットだけを選ぶことができ、多数のコミットがある場合には「git cherry-pick」よりも効果的です。

ブランチのミラーリングとリベース:これは、私がAndroidのプロジェクトに携わっているときに直面したことです。Googleがブランチをリリースし、Qualcommなどのチップセット会社がそのブランチを受け、別の長期的な戦略を決めて管理し、最終的にリリースしていました。リリース戦略を確定するためには、マージ/リベースという戦略が欠かせません。以前のリリースブランチで利用可能な修正と、変更の複雑さに基づいて、リベースとマージのどちらを選択するかを決定します。チップセットメーカーからリリースブランチを取得する他のサードパーティーのモバイル企業も、同様の戦略を採用していました。これは、他社のリリースを開発のベースブランチとして扱い、そこから製品をリリースする企業にとって、非常に重要なプロセスです。理想的には、このプロセスは自動化され、人手をかけずに管理されることが望ましいです。

リベースとブランチング戦略を活用する

最近Harnessでは、masterブランチをきれいに保ち、リリースプロセスを合理化するために、新しいブランチ戦略を導入しました。Harnessのコアリポジトリーでdevelopブランチがデフォルトのブランチとして機能します。開発者はdevelopブランチから機能/バグフィックスブランチを生成する必要があり、PRチェックはdevelopブランチで実行されます。そして、開発中の全ての変更がdevelopブランチにマージされます。

このブランチの考え方は、開発段階の早い段階でバグを見つけるためのものです。そのため、毎日developブランチを構築し、それをPre-QA環境にデプロイしています。さまざまなチームがPre-QA環境で自動化スイートを実行し、全てがうまくいったら、developブランチの変更をmasterブランチに移植します。ここで重要な役割を果たすのがリベースです。

マージではなくリベースを選択するのには、2つの理由があります。

  1. masterブランチのブランチ履歴をきれいに保つ。
  2. 長期的にはリバートが困難になるマージコミットの導入を回避する。

次の図は、私たちのブランチングと自動化戦略についての概略を示しています。

 

image-18-6b30e388-1920w.webp

まとめ

歴史的に見れば、Gitのリベースとマージには混乱があり、いつ何を使うべきなのかがわかりません。この記事では、リベースとマージがどのような場面で適切なのかを明らかにし、開発のさまざまな段階においてどのような戦略をとるべきかを決める助けになればと思います。

Gitの話題では、最近、Git Syncの体験談Git Branchingの記事を公開しました。Gitの知識を深めたい方は、ぜひご一読ください。


この記事はHarness社のウェブサイトで公開されているものをDigital Stacksが日本語に訳したものです。無断複製を禁じます。原文はこちらです。

Harnessに関するお問い合わせはお気軽にお寄せください。

お問い合わせ