Почему у этого черешни есть конфликт?
Я знаю 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? Какие детали вишни работают в этом случае?
2 ответа
Попробуйте еще раз свой вишневый кир после:
git config merge.conflictstyle diff3
Вы получите более подробную разницу:
<<<<<<< HEAD
||||||| parent of 5b2a14c... dev add line c
b
=======
b
c
>>>>>>> 5b2a14c... dev add line c
Это показывает, что при применении патча, представленного dev
ГОЛОВА (b
а также c
), Git не знает общего предка; это зависит от:
- непосредственный родитель выбранного вишни коммита (показывая, что он добавляет строку '
c
"после строки"b
") - целевой коммит (который не показывает строки
b
на все, на что он мог бы применить добавленное изменение "c
")
Отсюда и конфликт.
Сбор вишни не похож на слияние (которое ищет базу слияния).
Cherry-picking берет коммит и применяет внесенные изменения.
Здесь внесены изменения: добавить 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
)
Технически, так как вы редактируете одну и ту же строку одного и того же файла в разных ветках, Git видит в этом конфликт. Cherrypicking, хотя технически не является операцией "слияния", все же ищет те же типы конфликтов и просит их разрешить.
Для конфликтующих путей индексный файл записывает до трех версий, как описано в разделе "TRUE MERGE" в git-merge[1]. Файлы рабочего дерева будут содержать описание конфликта, заключенного в скобки с обычными маркерами конфликта <<<<<<< и >>>>>>>.
Из документации git-scm