Возникла у меня на работе необходимость объединить два 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 коммитов.
По идее надо запрещать людям добавлять новые изменения во время крупных слияний. Так будет возникать меньше затруднительных ситуаций.
Comments
comments powered by Disqus