リベースは、各差分の変更を「再生」し、新しいコミットを作成することによって機能します (古いコミットはそのまま残りますが、非表示になり、最終的に期限切れになります)。コミットを「再生」する方法は、 としてより直接的に利用できるgit cherry-pick
ため、最初にこれについて説明します。
チェリーピックを行うには、コミットで行われた変更を抽出する必要があります。結果の差分は、差分に含まれるコンテキストを使用して、他の (異なる) コミットに適用 (「パッチ」) できます。ただし、コミットは変更として保存されないため、<a href="https://stackoverflow.com/a/8198276/1256452">各コミットはソースの完全な「スナップショット」であり、cherry-pick で計算する必要があります。コミットによって提供される変更。これは、コミットをその親コミットと比較することによって行われます。
これは線形履歴ではうまく機能しますが、マージがある場合はうまくいきません。特に、マージ コミットには、定義上、少なくとも 2 つの親があります (3 つ以上の親を持つマージは珍しいですが、git では許可されています)。2 つの親を持つコミットがあり、diff を作成するときにどちらgit cherry-pick
の親を考慮するかを選択する明白な方法がない場合、単純に不満を持って停止します。-m
オプションを使用して、マージコミットをチェリーピックするときに気になる親を提供できます。
rebase コマンドは別のアプローチを採用しています。デフォルトでは、マージが不要であることを期待して、マージを完全に排除します。マージが重要な場合 (明らかにここでそうであるように)、これはチェリーピックの失敗につながります。
rebase コマンドには-p
(aka --preserve-merges
) オプションがあります。この場合、マージを維持しようとします。この特定のケースでは、元のベース コミットに対してコミット シーケンスを再生している場合、マージを維持するリベースが機能するはずです。
詳細については、ドキュメントを参照してください。