Git Merge Diff3 стиль нуждается в объяснении

Я объединил две ветви, и возникли конфликты, мне понадобятся некоторые подсказки, где он начинается, где он заканчивается и т. Д. Я заменил код на некоторые фальшивые данные, чтобы было легче читать и говорить.

<<<<<<< HEAD
    aaaaaa
||||||| merged common ancestors
<<<<<<< Temporary merge branch 1
    bbbbbb
=======
    cccccc
>>>>>>> mybranch
    dddddd
<<<<<<< HEAD
    eeeeee
||||||| merged common ancestors
    ffffff
||||||| merged common ancestors
    gggggg
=======
>>>>>>> Temporary merge branch 2
=======
    hhhhhh
>>>>>>> mybranch

2 ответа

Решение

Что вы видите в этом примере (с Temporary merge branch маркеры) - это результат сравнения diff3 с конфликтом слияний. Я объясню это с помощью последовательности определений.

Определения

  • база слияния: фиксация, в которой две ветви слияния, от которых произошли последние изменения, произошли недавно. При возникновении конфликта слияния разные изменения были внесены в одни и те же строки в обеих ветвях. База слияния содержит данные о том, какими были эти строки до того, как одна из веток изменила их
  • объединенные общие предки: diff3 выводит дополнительную "среднюю" секцию, показывающую линии, как они были в базе слияния. Это отправная точка для обеих веток.
  • Перекрестное слияние: история слияния, когда две ветви сливаются друг с другом так, что нельзя было бы выполнить слияние в ускоренном режиме. Я приведу пример ниже. В ситуации перекрестного слияния существует несколько баз слияния.
  • Временная ветвь слияния: Когда существует несколько баз слияния, diff3 пытается объединить их вместе (используя временные ветви слияния), чтобы сформировать единого общего предка для отображения в средней части diff3. Это работает бесперебойно, когда нет конфликтов, но когда есть конфликты, вы видите маркеры конфликтов ветки временного слияния в разделе общих слитых предков.

Пример сценария конфликта слияния

Перекрестное слияние происходит всякий раз, когда две ветви сливаются друг с другом в разные моменты времени.

m3 *
   |\
   | \
   |  * B1
   |  |
m2 *  * B0
   |\/|
   |/\|
m1 *  * A
   | /
   |/
m0 *

Рассмотрим эту последовательность событий:

  • m0 существует как происхождение / м астра
  • Я создаю ветку feature-A с одним коммитом A
  • m1 получает обязательство освоить кем-то еще
  • Я начинаю новую ветку feature-B что основывается на A
  • Я сливаю origin/master (m1) в feature-B, Это конфликтует, и я разрешаю это. Коммит слияния B0,
  • Я реализую функцию-B и фиксирую работу как B1,
  • feature-A готово к отправке, поэтому кто-то объединяет его в master, Это конфликтует. Они разрешают это, но их разрешение отличается от разрешения в B0, Коммит слияния m2,
  • feature-B готово к отправке, поэтому кто-то объединяет его в master, git пытается определить базу слияния, но m1 а также A оба квалифицируются в равной степени как базы слияния. мерзавец сливается m1 а также A во временной ветви слияния, что приводит к конфликту. Мы видим вывод diff3 в объединенном разделе общих предков, аналогично вопросу ОП.

Чтение вывода

Если diff3 выключен, конфликт слияния будет выглядеть так:

<<<<<<< HEAD
    aaaaaa
=======
    hhhhhh
>>>>>>> mybranch

Во-первых, со всеми дополнительными маркерами вы захотите определить действительные конфликтующие строки, чтобы вы могли отличить их от вывода общего предка diff3.

конфликт с объединенным общим предком размыт

аааааахххххх, это немного лучше.;-)

В случае, когда два разрешения конфликтов конфликтуют, aaaaaa а также hhhhhh эти две резолюции.

Далее рассмотрим содержание объединенного общего предка.

слились конфликты общих предков, сгруппированы

С этой конкретной историей слияний существовало более 2 баз слияний, для которых требовалось несколько временных ветвей слияния, которые затем объединялись. Результат, когда есть много оснований слияния и конфликтов, может стать довольно волосатым и трудным для чтения. Некоторые говорят, что не беспокойтесь, просто отключите diff3 для этих ситуаций.

Также имейте в виду, что внутренне git может решить использовать разные стратегии слияния для автоматического разрешения конфликтов, поэтому вывод может быть трудным для понимания. Извлекайте из этого смысл, если можете, но знайте, что он не предназначен для потребления человеком. В этом случае возник конфликт при объединении mybranch в Temporary merge branch 1 между bbbbbb а также cccccc, Линия dddddd не было конфликтов между временными ветвями слияния. Затем произошел отдельный конфликт при объединении Temporary merge branch 2 в HEAD, с несколькими общими предками. HEAD разрешил конфликт путем слияния ffffff а также gggggg как eeeeee, но Temporary merge branch 2 разрешил тот же конфликт, удалив (или переместив) строку (таким образом, между ====== а также Temporary merge branch 2,

Как вы решаете конфликт, как этот? Хотя технический анализ может быть возможен, наиболее безопасным вариантом является, как правило, вернуться назад и просмотреть историю во всех вовлеченных ветвях вокруг конфликта и вручную создать решение, основанное на вашем понимании.

Как избежать всего этого

Эти конфликты являются худшими, но есть некоторые способы поведения, которые помогут предотвратить их.

  1. Избегайте перекрестных слияний. В приведенном выше примере feature-B слиты origin/master как B0, Возможно, что это объединение, чтобы оставаться в курсе с мастером, не было необходимости (хотя иногда это и так). Если origin/master никогда не был объединен в feature-B, не было бы слияния, и m3 был бы нормальный конфликт с A как единственная база слияния.

    m3 *              m3 *
       |\                |\
       | \               | \
       |  * B1           |  * B1
       |  |              |  |
    m2 *  * B0   VS   m2 *  |
       |\/|              |\ |
       |/\|              | \|
    m1 *  * A         m1 *  * A
       | /               | /
       |/                |/
    m0 *              m0 *
    
  2. Будьте согласны с разрешением конфликтов. В этом примере конфликт временной базы слияния произошел только потому, что m2 а также B0 были разные разрешения конфликтов. Если бы они разрешили конфликт одинаково, m3 было бы чистое слияние. Но поймите, что это простое слияние, которое должно иметь такое же разрешение. Другие ситуации могут по праву иметь разные разрешения. Ситуация усложняется, когда между точками слияния существует более двух баз слияния и несколько коммитов. Тем не менее, если вы сознательно не согласны с разрешением конфликтов в критических ситуациях, ожидайте головные боли позже.

Вот статья о стиле слияния в git diff3. Это указывает на то, что трудно сказать, добавляются или удаляются строки в этом стиле.

Я предлагаю вам уточнить свой вопрос, если вы ищете конкретную информацию. Трудно сказать, что вы спрашиваете.

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