Git MergeとGit Rebaseの概要:それらの機能と使用するタイミング

開発者として、私たちの多くはMergeとRebaseを選択する必要があります。私たちがインターネットから得たすべての参考文献で、誰もが「Rebaseを使用しないでください。深刻な問題を引き起こす可能性があります。」と考えています。そうするために。

Git MergeとGit Rebaseは同じ目的を果たします。それらは、複数のブランチからの変更を1つに統合するように設計されています。最終的な目標は同じですが、これらの2つの方法は異なる方法でそれを達成します。より優れたソフトウェア開発者になるにつれて、違いを知ることは役立ちます。

この質問はGitコミュニティを分裂させました。常にリベースする必要があると考える人もいれば、常にマージする必要があると考える人もいます。どちらの側にもいくつかの説得力のある利点があります。

Gitマージ

マージは、バージョン管理システムを使用する開発者にとって一般的な慣行です。テスト、バグ修正、またはその他の理由でブランチを作成するかどうかに関係なく、マージは別の場所への変更をコミットします。具体的には、マージはソースブランチのコンテンツを取得し、ターゲットブランチと統合します。このプロセスでは、ターゲットブランチのみが変更されます。ソースブランチの履歴は同じままです。

マスターのマージ->機能ブランチ

長所

  • シンプルで使いやすい
  • 完全な履歴と時系列の順序を保持します
  • ブランチのコンテキストを維持します

短所

  • コミット履歴は、多くのマージコミットによって汚染される可能性があります
  • git bisectを使用したデバッグは難しくなる可能性があります

どうやるか

checkoutおよびmergeコマンドを使用して、masterブランチをfeatureブランチにマージします。

$ gitチェックアウト機能
$ git merge master
(または)
$ git merge master feature

これにより、機能ブランチに新しい「マージコミット」が作成され、両方のブランチの履歴が保持されます。

Gitリベース

Rebaseは、あるブランチから別のブランチへの変更を統合する別の方法です。 Rebaseは、すべての変更を単一の「パッチ」に圧縮します。次に、パッチをターゲットブランチに統合します。

マージとは異なり、リベースは、完了した作業をあるブランチから別のブランチに転送するため、履歴をフラット化します。その過程で、不要な履歴が削除されます。

リベースとは、変更が階層の最上部から下に向かってどのように通過するかであり、マージは、それらが上に戻る方法です。
機能ブランチをマスターにリベースします

長所

  • 潜在的に複雑な履歴を合理化します
  • 単一のコミットの操作は簡単です(たとえば、それらを元に戻す)
  • ビジーなブランチを使用したビジーなリポジトリでのマージコミットの「ノイズ」を回避
  • 単一のコミットにすることで中間コミットをクリーンアップします。これは、DevOpsチームに役立ちます。

短所

  • 機能を一握りのコミットに押しつぶすと、コンテキストが隠される可能性があります
  • チームとして作業する場合、公開リポジトリのリベースは危険な場合があります
  • さらなる作業:リベースを使用して、機能ブランチを常に更新し続ける
  • リモートブランチでリベースするには、プッシュを強制する必要があります。人々が直面する最大の問題は、プッシュを強制するが、Gitプッシュのデフォルトを設定していないことです。これにより、ローカルとリモートの両方で同じ名前を持つすべてのブランチが更新され、対処するのは恐ろしいことです。
誤ってリベースし、意図せずに履歴を書き換えると、深刻な問題につながる可能性があるため、自分が何をしているかを確認してください!

どうやるか

次のコマンドを使用して、機能ブランチをマスターブランチにリベースします。

$ gitチェックアウト機能
$ git rebase master

これにより、機能ブランチ全体がマスターブランチの上に移動します。これは、元の(機能)ブランチの各コミットに対して新しいコミットを作成することにより、プロジェクト履歴を書き直すことでこれを行います。

インタラクティブなリベース

これにより、コミットが新しいブランチに移動するときにコミットを変更できます。これは、ブランチのコミット履歴を完全に制御できるため、自動リベースよりも強力です。通常、これは、機能ブランチをマスターにマージする前に、厄介な履歴をクリーンアップするために使用されます。

$ gitチェックアウト機能
$ git rebase -i master

これにより、移動しようとしているすべてのコミットが一覧表示され、エディターが開きます。

22d6d7cメッセージをコミットする#1
44e8a9bメッセージをコミットする#2
pick 79f1d2hコミットメッセージ#3

これは、リベースが実行された後のブランチの外観を正確に定義します。エンティティを並べ替えることで、履歴を好きなように見せることができます。たとえば、ピックの代わりに、フィックスアップ、スカッシュ、編集などのコマンドを使用できます。

使用するもの

だから何が最高ですか?専門家は何をお勧めしますか?

すべてのチームは異なるため、どちらかを一般化して決定することは困難です。しかし、どこかから始めなければなりません。

チームは、Gitリベースとマージポリシーを設定するときに、いくつかの質問を考慮する必要があります。結局のところ、1つのワークフロー戦略が他の戦略よりも優れているわけではないからです。それはあなたのチームに依存しています。

組織全体のリベースのレベルとGitの能力を考慮してください。マージのトレーサビリティと履歴と比較して、リベースのシンプルさを評価する程度を決定します。

最後に、明確な分岐戦略のコンテキストでマージとリベースの決定を検討する必要があります(分岐戦略の詳細については、この記事を参照してください)。成功する分岐戦略は、チームの組織を中心に設計されています。

私は何をお勧めしますか?

チームが成長するにつれて、常にマージポリシーを使用して開発の変更を管理または追跡することが難しくなります。クリーンで理解可能なコミット履歴を得るには、Rebaseを使用するのが合理的かつ効果的です。

次の状況とガイドラインを考慮することで、Rebaseを最大限に活用できます。

  • ローカルで開発している場合:作業を他の人と共有していない場合。この時点で、履歴を整理するために、マージよりもリベースを優先する必要があります。リポジトリの個人的なフォークを取得していて、それが他の開発者と共有されていない場合、ブランチにプッシュした後でもリベースしても安全です。
  • コードをレビューする準備ができました:プルリクエストを作成しました。他の人はあなたの作品をレビューしていて、ローカルレビューのために彼らのフォークにそれをフェッチする可能性があります。この時点では、作業をリベースしないでください。 「リワーク」コミットを作成し、機能ブランチを更新する必要があります。これにより、プルリクエストのトレーサビリティが確保され、偶発的な履歴破損が防止されます。
  • レビューが完了し、ターゲットブランチに統合する準備が整いました。おめでとうございます!機能ブランチを削除しようとしています。これ以降、他の開発者がこれらの変更をフェッチマージしないため、これはあなたの履歴をサニタイズするチャンスです。この時点で、履歴を書き換え、元のコミットとそれらの厄介な「pr rework」および「merge」コミットを、フォーカスされたコミットの小さなセットに折り畳むことができます。これらのコミットの明示的なマージの作成はオプションですが、価値があります。機能がマスターに卒業したときを記録します。

結論

この説明がGitのマージとGitのリベースに関する洞察を与えてくれることを願っています。マージとリベースの戦略は常に議論の余地があります。しかし、おそらくこの記事はあなたの疑念を払拭し、あなたのチームに合ったアプローチを採用するのに役立つでしょう。

GitのワークフローとGitの概念について書くことを楽しみにしています。次に書いてほしいトピックについてコメントしてください。乾杯!

コード=コーヒー+開発者

ここに別の便利なリファレンスがあります

  • Gitの分岐戦略を採用する方法

ソフトウェア開発者のためのコーディングスクール