Подтвердить что ты не робот

Git слияние diff3 стиль требуется описание

Я объединил 2 ветки и конфликты, мне нужны некоторые подсказки, где они начинаются с того места, где они заканчиваются, и т.д. Я заменил код некоторыми поддельными данными, чтобы облегчить их чтение и обсуждение.

<<<<<<< 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
4b9b3361

Ответ 1

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

Определения

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

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

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

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

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

  • m0 существует как начало / m aster
  • Я создаю ветвь функции 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 оба одинаково квалифицируются как базы слияния. git объединяет m1 и A во временную ветвь слияния, что приводит к конфликту. Мы видим вывод diff3 в разделе объединенных общих предков, аналогичном вопросу OP.

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

С diff3 off этот конфликт слияния будет выглядеть так:

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

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

conflict with merged common ancestor blurred

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

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

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

merged common ancestor conflicts, grouped

С этой конкретной историей слияния существовало более двух баз слияния, что требовало нескольких временных ветвей слияния, которые затем были объединены. Результат, когда есть много оснований слияния и конфликтов, может стать довольно волосатым и трудночитаемым. Некоторые говорят, что не беспокойтесь, просто отключите 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.

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

Избегайте всего этого

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

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

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

Ответ 2

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

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