Последствия использования трансплантата в Mercurial
Недавно было несколько вопросов о пропуске изменений при поддержке веток релиза в Mercurial. Например:
- Mercurial: специфичные для ветки изменения продолжают возвращаться после фиктивного слияния
- Почему отказы Mercurial в одной ветви влияют на другие ветви?
Так как это было введено в 2.0, я задавался вопросом об использовании graft
чтобы избежать этой проблемы. Дано дерево ревизий, подобное этому:
A---B---C---D---E---F---G---H---I---J
Предположим, нам нужно создать ветку релиза, которая пропускает изменения зла E
,
hg update -r D
hg graft "F::J"
давая нам:
A---B---C---D---E---F---G---H---I---J
\
--F'--G'--H'--I'--J'
- Q1: что только что произошло здесь? я могу понять, что
transplant
сгенерировал бы патчи изF::J
, а затем применил их наD
, ноgraft
Говорят, что используется трехстороннее слияние, а не патчи. Так....... как это работает? Почему лучше?
Допустим, я сейчас исправлю E
и слить это в мою ветку релиза.
--E2-----------------
/ \
A---B---C---D---E---F---G---H---I---J---M1
\ \
--F'--G'--H'--I'--J'---------M2--
M1 - прямое слияние; ничего особенного там нет. M2 - это объединение ветвей, которые имеют "одинаковые" (или, по крайней мере, эквивалентные) изменения.
- Q2: это слияние является обычным 3-сторонним слиянием, используя
D
,J'
а такжеM1
? - Q3: Mercurial сохранял / использовал дополнительную информацию об операции пересадки, чтобы помочь ей с слиянием?
И наконец...
- Q4: Каковы потенциальные проблемы с таким потоком?
2 ответа
При обновлении до D
и привить F::J
Mercurial запускает ряд слияний. Это начнется с этого слияния:
M = three_way_merge(local=D, other=F, base=E)
Если мы напишем +d
для дельты между штатами C
а также D
, тогда мы начнем с:
+d +e +f
---- C ---- D ---- E ---- F ----
Поверните график на 90 градусов по часовой стрелке, и вышеупомянутое трехстороннее слияние выглядит так:
-e
.---- D
/
E
\
'---- F
+f
То есть мы делаем вид, что начали с E
и применил противоположность -e
чтобы добраться до D
, Я думаю, как обратный патч +e
, Начиная в E
мы также пошли, чтобы заявить F
с нормальной дельтой +f
, Здесь нет ничего странного - у нас есть все состояния (D
, E
, а также F
) в репозитории уже. Итак, видно, как это, ясно, что мы можем объединить D
а также F
,
Слияние - это вопрос "завершения бриллианта". Итак, мы находим новое состояние M
это смесь D
а также F
и откуда разница D
в M
похож на +f
и разница с F
в M
похож на -e
, Это выглядит так:
-e +f'
.---- D ----.
/ \
E M
\ /
'---- F ----'
+f -e'
+f
дельта стала +f'
и -e
дельта стала -e'
, Это обычное трехстороннее слияние, но эффект интересен: мы применили F
на D
вместо E
!
После слияния второй родитель M
в F
упал:
-e +f'
.---- D ----.
/ \
E M
\
'---- F
+f
Повторим: мы скопировали "эффект" F
на D
то есть мы нашли дельту (+f'
) это относится к D
дают тот же эффект, что и когда +f
был применен к E
, Мы можем немного выпрямить график, чтобы получить:
+f'
--- D ---- M
\
'---- E ---- F
+e +f
Результатом является то, что F
привит на D
используя полный трехсторонний механизм.
Q1: что только что произошло здесь? Так....... как это работает? Почему лучше?
A1: Использование слияний лучше, чем исправлений, так как механизм слияния учитывает такие вещи, как переименования.
Q2: Это слияние - обычное трехстороннее слияние с использованием D, J'и M1?
A2: Да, прививка не меняет топологию графа.
Q3: Mercurial сохранял / использовал дополнительную информацию об операции пересадки, чтобы помочь ей с слиянием?
A3: Нет.
Q4: Каковы потенциальные проблемы с таким потоком?
A4: С точки зрения слияния все должно работать хорошо. Это дублирует некоторую историю, которая может сбивать людей с толку.
Q1: это помогает, когда есть конфликты. Тогда вы можете использовать свой обычный инструмент слияния (для меня это встроенные маркеры конфликтов, которые я редактирую с помощью режима Emacs smerge-mode).
Q2: это нормальное слияние.
Q3: Нет.
Q4: я думаю, что некрасиво иметь две почти одинаковые ветви.