Конфликтные слияния веток и git merge-base
Когда у вас есть две ветки разработки, которые достаточно сильно друг от друга отличаются, периодически возникают проблемы с их слиянием (merge).
Допустим, текущая ветка называется master
, а новая ветка — rails32
(и это реальный случай из
практики разработки Групона). В master
у нас используется rails 3.0, а в rails32
, как вы догадались из названия, —
rails 3.2.
Так вот для того, чтобы rails32
была всегда актуальной, периодически в нее вливался master
. И все бы ничего, но из-за
asset pipeline переделок было значительное количество, поэтому часто у нас возникали конфликты при слиянии. У меня не
всегда получалось по дифу конфликта понять, что надо оставить, особенно когда код писал не я. Чаще всего такие ситуации
возникают, когда поменялся отступ, например, какой-то блок куда ушел внутрь еще одного условия if
. Тогда я пользовался
следующей конструкцией:
git diff `git merge-base master rails32`..master -- conflicted.filename
Эта команда показывает, что поменялось в файле conflicted.filename
в ветке master
с момента последнего слияния веток.
Почти всегда этот diff давал мне ясное понимание того, как надо разрешить конфликт.
Сама команда merge-base
возвращает ближайшего общего предка для двух веток, то есть sha-id какого-то комита.
$ git merge-base master rails32
74b67a8090fa10549ab238928c68368f10b5a415
К несчастью, мой любимый плагин к vim vim-git не позволяет показать такой diff просто. И я не помню, чтобы какая-то IDE умела это. Хотя, казалось бы, такая очевидная и нужная функция.