リモートリポジトリーの履歴がリベースにより変わってしまった時は
前回紹介した「リベースがリポジトリーを共有しているユーザーに与える影響の例」のように、もし他の人が「リモートリポジトリー」の既存の履歴を「リベース」により変更してしまうと、自分の「ローカルリポジトリー」の履歴と合わなくなる場合があります。まず、この状況に気づくことが大切です。
この状況に気づいたら、現状を把握します。
「リモートリポジトリー」の、どの履歴が変更されたのか、自分の「ローカルリポジトリー」の履歴とはどこが違うのか、違いを把握する必要があります。
ここで例として紹介するリポジトリーの履歴は、「リベースがリポジトリーを共有しているユーザーに与える影響の例」を参考にしてください。
マージの代わりにリベースしてみる
前回紹介した例では、Aさんは「My」ブランチと「リモートトラッキングブランチ」の「origin/master」ブランチを「マージ」 していました。ここでは、「Git」に履歴を自動的に把握してもらい、「リベース」を行う流れを紹介します。
「Git」では履歴の状況を把握し、自分のコミットを変更履歴のリベースを行う機能を提供しています。
この方法は、「リモートトラッキングブランチ」に自分のブランチを「リベース」します。
注意
これは1つの方法ですが、必ずしも適切な方法とは限りません。「リモートリポジトリー」の既存の履歴が変わってしまった時に、どう対処するのが良い方法なのか、手段の検討は必要です。
1.現在のリモートリポジトリーの状態
現在の「リモートリポジトリー」は、以下のようになっています。「5.コミットの取り消しとリベース(リモートリポジトリー)」の状態です。
2.Aさんのローカルリポジトリー
Aさんの「ローカルリポジトリー」は、以下のようになっています。「6.リモートリポジトリーをフェッチ(Aさんのローカルリポジトリー)」の状態です。
3.リベースを行う(Aさんのローカルリポジトリー)
Aさんは、「My」ブランチを「origin/master」ブランチに「リベース」します。リベース元は「My」ブランチです。
リベース先は「origin/master」ブランチです。
ここから先は「Git」が処理を行います。
4.違いの検出(Aさんのローカルリポジトリー)
まず「Git」は、Aさんの「ローカルリポジトリー」にしかない「コミットオブジェクト」を検出します。以下のコミットが、Aさんの「ローカルリポジトリー」にしかない「コミットオブジェクト」です。
- Commit2
- Commit3
- Commit4
- Commit6
- Commit7
5.マージコミットの除外(Aさんのローカルリポジトリー)
次に「マージコミット」 を除外します。「Commit6」と「Commit7」は「マージコミット」 です。
以下のコミットに絞られます。
- Commit2
- Commit3
- Commit4
6.変更された変更履歴にあるコミットを除外(Aさんのローカルリポジトリー)
Bさんによって変更された履歴にある「コミットオブジェクト」を検出し、その「コミットオブジェクト」を除外します。「Commit4」と「Commit4’」は同じ変更内容(重複している)なので、「Commit4」を除外します。
以下のコミットに絞られます。
- Commit2
- Commit3
7.リベース完了(Aさんのローカルリポジトリー)
抽出した 「Commit2」と「Commit3」を「Commit4’」に結合します。もし「マージコンフリクト」が発生したら、通常のリベース時と同じように、ユーザーがコンフリクトの解消を行う必要があります。
これで変更履歴がスッキリしました。
「7.ブランチのマージ(Aさんのローカルリポジトリー)」と比較してみてください。
期待通りに動作しないこともある
「リベース」は万能ではありません。「コミットオブジェクト」の変更内容が同じであるかどうかを自動検出する過程において、自動検出が期待通りに行われないこともあります。
上記の「6.変更された変更履歴にあるコミットを除外」で、「Commit4」と「Commit4’」の変更内容が異なると判断された場合、ユーザーの期待通りに検出が行われません。
この場合、ユーザーが期待する結果とは異なる結果になります。
「マージ」 にせよ「リベース」にせよ、結局ユーザーがどう対処したほうがいいのかを検討し、結果が期待通りの内容になっているか確認する必要があります。
このように、「リベース」による「リモートリポジトリー」の履歴の改変が、面倒な結果につながる可能性があるということを、よく理解しておく必要があります。