マージとリベースは同様の目標を達成しますが、実行する方法は異なります。どちらもブランチの操作や複数のユーザーとのコラボレーションの管理に役立ちますが、互換性はなく、リベースは適切に行わないと有害になる可能性があります。
リベースはどうなるのでしょうか?
リベースは非常に複雑なので、その方法を理解することが重要です
git
意味を理解したいのであれば、内部で機能します。
Git はコードを一連の編集として保存します。これを逆方向に進む連鎖のように考えることができます。各編集、つまり「コミット」は、前のコミットの ID を参照し、前のコミットからの変更内容を含みます。このチェーンはあなたのコンピュータにのみ保存されます。 Git クライアントは、以下を実行しない限り、他の Git クライアントと通信しません。
fetch
または
push
(
pull
本当にただです
fetch + merge
ローカルブランチと)、それでも、共有リモートリポジトリとのみ通信しています。
ブランチはさらに複雑です。 Git は、ブランチを処理するときに 1 つのものだけを保存します。それは、ブランチの最後にあるコミットの ID です。このように、これらはレコード プレーヤーの再生ヘッドのように考えることができます。ブランチヘッドを特定の位置に配置すると、ブランチヘッドがチェーンを逆方向に進み、コードを「再生」して最終バージョンに到達します。コミットするたびに、ローカル git クライアントは自動的に再生ヘッドを新しいコミットに移動します。
フィーチャーをマスターにマージしたい場合は、次を実行します。
git チェックアウト マスター
gitマージ機能
これにより、新しいマージ コミットが作成され、競合がある場合は手動で解決する必要があります。
git merge
コマンドは、マスター プレイヘッドを新しいマージ コミットに移動し、フィーチャー プレイヘッドが不要になったので削除します。
コードをマージするこの方法には、次の 3 つの問題があります。
- 特に機能の開発に時間がかかる場合は、機能ブランチに含めたい変更がマスター ブランチに存在する可能性があります。
- ブランチを操作するたびにマージプロセスを強制されるのは面倒です。
- コミット履歴は乱雑ですが、これは主に見た目の問題です。
リベースはこれらの問題を解決しようとしますが、成功の程度はさまざまです。ブランチを開始した場所に変更をリベースします。ブランチ全体が持ち上げられ、現在のマスター ブランチの終端に転送され、そこで終端に接続されます。 master ブランチはそのまま残され、引き続き自由にコミットを受信できます。
ただし、コミットは不変であるため、実際には移動されません。むしろ、それらはコピーされるため、新しいコミット ID が生成されます。以前のコミットは取り残されたままになり、Git ファイルに隠れますが、再生ヘッドが別の場所に移動したため、二度と表示されることはありません。
コマンドラインからこのプロセスを実行するには、次のコマンドを実行します。
gitチェックアウト機能
git プル
gitリベースマスター
これにより、ブランチが開き、現在の変更がマスターにプルされ、フィーチャー ブランチがマスター ブランチにリベースされます。
この時点で、機能ブランチのコードはより最新のものになり、これが
git rebase
の唯一の実際の機能です。リベースではマージ コミットが作成されず、マスターのプレイヘッドが移動されないため、ブランチはマージされません。
リベース後にマージしたい場合は、次を実行します。
git チェックアウト マスター
gitマージ機能
マスターの再生ヘッドが機能の再生ヘッドを置き換えると、次のようになります。
つまり、master ブランチを更新するには最後にマージする必要があるため、リベースを行ってもマージの処理の問題は解決されません。ただし、リベースのプロセスでは変更を「マージ」する必要があり、それでも競合が発生する可能性があるため、最後の実際の
merge
コマンドは問題なく実行されるはずです。ブランチでの作業を続けたい場合は、変更を「マージ」する必要があります。
共有ブランチをリベースしないでください
コピーをリベースするとどのようにコミットされ、プレイヘッドが取り残されたままになるか覚えていますか?共有コードを使用している場合、これは実際には大きな問題です。機能ブランチを作成し、同僚がテストできるようにそれをリポジトリにプッシュしたとします。それはまったく問題ありませんが、そのうちの 1 つがブランチから分岐したい場合、最終的にリベースすると次のようになります。
同僚の feature2 ブランチは現在、古いコミット チェーンを参照しています。 feature2 ブランチは同僚のコンピュータに保存されているため、Git クライアントはこれを知る方法がありません。また、変更をプッシュするまでは、リベースしたことを知る方法もありません。
リベースすると、すべてのコミットがコピーされるときに、feature2 ブランチはコピーされませんでした。たとえそれができたとしても、同僚のローカル Git リポジトリに影響を与えず、すべてが同期しなくなります。ここでの解決策は、feature2 をその位置にある feature にリベースすることですが、これは Git 標準から見ても面倒です。これは非常に単純な例にすぎません。
結論としては、 ローカルで作業していない場合はリベースしないでください 。
リベースがマージよりも優れているのはどのような場合ですか?
ブランチの開発に時間がかかる場合は、リベースによって「ブランチ シンドローム」の問題が解決されます。この問題では、コードが作業中のマスターと比べて古すぎるため、作業を続けるにはコードを更新する必要があります。一般的に言えば、この問題はできる限り回避する必要がありますが、問題が発生した場合はリベースによって修正できます。
毎日小さな増分変更を加えているだけの場合は、代わりにローカルの master ブランチで作業し、変更をプッシュする準備ができたら プル リクエスト を使用する必要があります。これらは、マージが承認される前にコードを保存するために特別に作成されたトピック ブランチのモデルを使用します。
ただし、毎週のタイムスパンで作業していて、最終的に複数のプル リクエストを作成して複数回マージすることになる場合は、コードをもう少し長く作業し、更新のためにローカルでリベースし、次の時点で 1 つのプル リクエストを実行することができます。テストや監督者との会話の量を減らすことが目的です。リベースは主にローカルで行われるため、承認を待たずにステージング ブランチで実行できます。
他に誰もあなたのブランチに依存していない場合は、ブランチのマージ前にリベースして、コミット履歴をクリーンで 1 次元にすることができます。ただし、従来のマージは確かに醜いものの、マージ コミットは完全に非破壊的であるため、追跡とデバッグが容易であると主張する人もいます。いずれの場合でも、リベースは変更がマージされる直前に実行する必要があります。そうしないと、変更が承認される前にマスターが更新されるという問題が発生する可能性があります。





