Этот рисунок:
master : A - BC
\
dev : A - B - C
подразумевает, что есть какая-то связь между C
и BC
.
Нет такой ссылки, но есть связь между A
и B
(в частности, с B
обратно на A
).Таким образом, более точный рисунок:
A--D <-- master
\
B--C <-- dev
, где D
имеет такой же снимок , что и C
, но не имеет отношения, отсюда и название D
.
Это источник всей проблемы:
Я вижу много конфликтов, когда пытаюсь слить dev
в master
снова или наоборот.
Что касается Git, точка, в которой dev
и master
соответствуют, является commit A
.Поэтому Git должен взять diff с A
до C
и применить его снова к master
, который - в глазах Git - еще не имеет B
или C
.
Мы хотим продолжать строить функции поверх dev
ветви и сохранять ее историю, поэтому удаление ее и создание новой ветви на основе master
не будет возможным.
InВ этом случае прекратите делать сквош, потому что сквош эффективно «убивает» ветку: вы никогда не должны делать больше с коммитами B-C
.Просто сделай реальное слияние.В веб-интерфейсе GitHub это можно сделать, выбрав «объединить»;из командной строки используйте git merge --no-ff
.Затем вместо нового полностью независимого коммита D
вы получите коммит слияния (который я по-прежнему буду называть D
):
A------D <-- master
\ /
B--C <-- dev
Когда вы будете больше работать над dev
вы получите:
A------D <-- master
\ /
B--C--E--F <-- dev
и теперь вы можете сделать еще одно слияние.На этот раз нет необходимости в --no-ff
, хотя он все равно будет работать нормально;в веб-интерфейсе GitHub тоже нечего менять.Вы получите новый коммит слияния G
:
A------D-----G <-- master
\ / /
B--C--E--F <-- dev
Входными данными для этого второго слияния являются коммит C
в качестве базы слияния, коммит D
как --ours
и коммит F
как --theirs
, поэтому слияние пройдет гладко.Как и раньше, снимки в C
и D
будут совпадать, а снимки в F
и G
будут совпадать.
Если вы хотите увидеть, что произошло строго с точки зренияmaster
, используйте:
git log --first-parent master
Это указывает git log
смотреть только на первый родительский элемент каждого коммита слияния.То есть Git начнет с показа коммита G
, на который master
очков.Затем он перейдет от G
к первому родительскому элементу D
и покажет этот коммит.Затем он перейдет от D
к первому родительскому элементу A
и покажет этот коммит.Поскольку более ранних коммитов нет вообще, git log
теперь останавливается с завершением своей работы.
(Конечно, если есть коммиты до A
, git log
продолжит их показывать, новсе рисунки здесь не имеют коммитов до A
.)