web-dev-qa-db-ja.com

なぜこのチェリーピックに矛盾があるのですか?

知っている git cherry-pickは、指定されたコミットの変更を適用するために使用するコマンドですが、私はそれがどのように機能するかを本当に理解していないと思います。

レポがそのように振る舞うとしましょう:

git init

echo a>a
git add .; git commit -am 'master add line a'

git checkout -b dev
echo b>>a
git commit -am 'dev add line b'
echo c>>a
git commit -am 'dev add line c'

git checkout master

git cherry-pick dev

cherry-pickコマンドはうまく機能し、ファイルaを次のように変更します。

a

c

しかし実際には、次のメッセージが表示されました。

error: could not apply 08e8d3e... dev add line c
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

そして、私は実行します:

git diff

出力:

diff --cc a
index 7898192,de98044..0000000
--- a/a
+++ b/a
@@@ -1,1 -1,3 +1,6 @@@
  a
++<<<<<<< HEAD
++=======
+ b
+ c
++>>>>>>> 11fff29... abc

だから私の質問は:なぜgit-diffショーのような競合があるのですか?この場合のcherry-pickの動作の詳細は何ですか?

17
L_K

チェリーピックafterをもう一度やり直してください:

git config merge.conflictstyle diff3

より詳細な差分が表示されます。

<<<<<<< HEAD
||||||| parent of 5b2a14c... dev add line c
b
=======
b
c
>>>>>>> 5b2a14c... dev add line c

dev's HEAD(b and c)で表されるパッチを適用するとき、Gitは共通の祖先を知らないことを示しています;それは以下に従います:

  • チェリーピックコミットの直接の親(行 'c'の後に行 'b'が追加されることを示します)
  • 宛先コミット(追加された変更 'b'を適用できる行cはまったく表示されません)

したがって、対立。

Cherry-pickingmergemerge-base を検索します)とは異なります。

チェリーピッキングはコミットを取り、それが導入する変更を適用します

ここで導入された変更は次のとおりです。cの上にbを追加します。
そして、宛先コミットにはbがまったくないので、Gitの場合:

  • アップストリーム(宛先)コミットは「bを削除しました」(または、そもそもそれを持っていなかった、ここではそうですが、Gitはそれを知りません)、
  • ソースコミットにはbがあり、その上にcが追加されます。

Gitがそのパッチを適用しようとしたときに知っている限り(そしてそれがすべてgit cherry-pickが行うこと:パッチを適用します。厳選されたコミットの履歴をまったく検索しません)、それは競合です:同時変更。

解決策がどうあるべきか確信がある場合は、次のことができます。

> git cherry-pick -Xtheirs dev
[master 7849e0c] dev add line c
 Date: Wed Aug 17 08:25:48 2016 +0200
 1 file changed, 2 insertions(+)

次に、bcが元のコミットに競合なしで追加されます(オプション '-Xtheirs'を-に渡して解決する方法を示したため) デフォルトのマージ戦略recursive

22
VonC