master----\----commit A----cherry-picked changesets from topic---commit B--\----commit C----merge---
\ \ /
topic-----------------------------------------------------------merge---------/
~~~~~
^
+ here you merged B in topic
親としてコミット B を持つトピックに既にマージがあります。したがって、B はトピックに完全にマージされ、もうどこにもマージされません。
トピックに変更がないため、マージ自体または次のコミットのいずれかで、トピックにそれらを元に戻したようです。このような反転は、マージ アルゴリズムの通常のコミットであり、マスターにはマージされません。したがって、トピックをマスターにマージすると、このコミットの変更がマージされ、コミット B が元に戻ります。
B からの変更を元に戻すには、次のいずれかを行う必要があります。
- トピックに関する B の変更の反転を見つけて元に戻します。
git cherry-pick B
B ( ) を話題にチェリーピック。
- マージをやり直し、マージ後に新しいマージでトピックをリベースし、元のブランチを忘れてください。
あなたが気付かないうちに、変更がどのように元に戻された可能性がありますか? マージ中に競合が発生した場合、これらの変更はまだ必要ないと考えて、「ローカル」を使用してずさんに解決する可能性があります。しかし、Git (またはその他のバージョン管理システム) の観点から見ると、変更を確認して拒否したため、二度と取得することはありません。手動で再適用しない限り。
競合は、以前のチェリーピックによって簡単に引き起こされた可能性があります. 両方の側が同じに見える場合、アルゴリズムは競合を宣言しませんが、チェリーピックしてマージする場合、チェリーピックされたコードを一方の側で変更すると競合を宣言します。あなたが持っているとしましょう:
----\-- A -------- B' -- B2 --\
\ \
D -- B -- E -----------merge
whereは、行ったのと同じコードを選択して変更B'
しB
ます。その場合、チェリーピックは によって隠されているため、との間の競合を宣言するため、マージは一方の側がを行い、もう一方の側が を行ったことを確認します。そして、歴史を注意深く見なければ、この間違いを簡単に解決してしまうかもしれません。コミットを選択するときに、次のようにターゲットブランチをソースブランチに慎重にマージすると、問題を回避できます。B2
B
B
B2
B2
B
B2
----\-- A --------\- B' -\- B2 --\
\ \ \ \
D -- B -- E --m1-----m2----merge
リモートではチェリーピックされた変更のみが含まれているため、m1
チェリーピックが関与しない通常のマージでありm2
、ローカルバージョンで解決されます。これにより、以降のマージが正しく機能することが保証されます。
実際には、git がこれを自動的に行うためのマージ戦略を作成できるはずです。