Возникла у меня на работе необходимость объединить два merge в один. Делал большое и несколько конфликтное слияние. А во время этого в Gerrit на мою ветку успели залить что-то новое, вызвавшее новые конфликты с моим merge. Соответственно необходимо было слить эти изменения тоже. На тот момент я видел следующие варианты:
- Самый простой способ: сделать еще один
merge
. В итоге получаем еще один дополнительный commit и разветвленную историю. - Сделать полный
merge
заново. Повторять уже сделанное не хочется.
Я решил найти вариант, позволяющий в результате первого простого способа
получить один коммит. Оказалось эта операция не совсем очевидна. Как всегда в
последнее время, нашел решение на stackoverflow. Опишу весь процесс с
начала до конца с историей тестового репозитория (git log --oneline --graph
--decorate
):
- Итак, мы сделали какой-то абстрактный
merge
master в feature ветку с исправлением всех конфликтов:
$ git checkout feature $ git merge origin/master
* b8c37f7 (HEAD, feature) c' |\ | * 7020561 (origin/master) b * | 2a55e67 (origin/feature) b' |/ * b888f61 a
- Далее кто-то добавил что-то новое на feature ветку:
* 3820f07 (origin/feature) c' | * b8c37f7 (HEAD, feature) c' | |\ |/ / | * 7020561 (origin/master) b * | 2a55e67 b' |/ * b888f61 a
- Делаем дополнительный
merge
и видим не особо приятную историю:
$ git merge origin/feature
* 781dea7 (HEAD, feature) d' |\ | * 3820f07 (origin/feature) c' * | b8c37f7 c' |\ \ | |/ |/| | * 7020561 (origin/master) b * | 2a55e67 b' |/ * b888f61 a
- А теперь собственно решение с выправлением истории. Делаем
reset
на коммит, с которого надо делатьmerge
:
$ git reset --soft origin/feature
* 3820f07 (HEAD, origin/feature, feature) c' * 2a55e67 b' | * 7020561 (origin/master) b |/ * b888f61 a
- Далее симулируем
merge
с origin/master и делаемcommit
:
$ git rev-parse origin/master > .git/MERGE_HEAD $ git commit
* 3b01bf0 (HEAD, feature) d' |\ | * 7020561 (origin/master) b * | 3820f07 (origin/feature) c' * | 2a55e67 b' |/ * b888f61 a
Как видим в итоге получилась аккуратная история с необходимым полным слиянием
веток. Теперь можно делать push
. Данный способ можно использовать для
объединения любого количества merge коммитов.
По идее надо запрещать людям добавлять новые изменения во время крупных слияний. Так будет возникать меньше затруднительных ситуаций.
Комментариев нет:
Отправить комментарий