Почему у этого черешни есть конфликт?

Я знаю 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

Другие вопросы по тегам