知っている 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の動作の詳細は何ですか?
チェリーピック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-picking は merge ( merge-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(+)
次に、b
とc
が元のコミットに競合なしで追加されます(オプション '-Xtheirs
'を-に渡して解決する方法を示したため) デフォルトのマージ戦略recursive
)