Поговорим про слияния веток, м?
Вступление
Немного теории. Для начала предлагаю вкратце вспомнить пару терминов из git:
Ветка
Ветки имеют две функции: ответвляться и сливатся.
Предназначены разделять поток разработки. Если мы говорим про продуктовую разработку - с помощью веток мы можем разбить состояния продукта на версии (релизы/release), а для каждых релизов вести разработку несколько функциональных новшеств (фичи/features) разными или одним и тем же разработчиками.
Комиты
Комиты - снимок текущего состояния содержимого файла(ов).
git add . // git заносит файлы в stage area
Оттуда уже можно выполнить команду
git commit -m “комментарий по изменениям”
тем самым создать комит в ветке. (Как показано на рисунке выше)
Слияние. Git Merge
Что же, представим ситуацию, что показ нашего проекта требуется обновить.
Для этого в ветку master нужно слить последние изменения ветки stage (обычно в этой ветке находятся актуальные, полностью протестированные новые фичи)
Git предоставляет такую возможность, с помощью команды merge.
Для начала нам нужно перейти в ветку master.
git checkout master
git merge stage
Fast forward или быстрая склейка.
Хочу обратить ваше внимание после выполнения данной операции, git предупреждает нас в консоли, что произошло так называемое быстрая склейка” (fast-forward).
Это произошло потому, что комит S1 имеет в качестве родителя - последний коммит ветки master. Git видит, что параллельно разработки на ветке stage, в ветке master не было воспроизведено никаких изменений, следовательно, можно считать, что stage фактически является продолжением ветки master. Отсюда “быстрая склейка”.
В оригинальном переводе fast forward дословно переводиться с англ. на рус. как “быстрая перемотка”. Для удобства понимания я назвал это явление “быстрая склейка”
Трехстороннее слияние
Теперь представим, немного другую ситуацию, которая является самой распространенной.
Допустим у нас есть ветка dev, в которой находиться актуальное состояние проекта, с включением последних сливших функциональных новшеств. Обычно в продакшене это ветка только для разработчиков, мы там развлекаемся как можем (на самом деле нет).
Вот, пришла задача - разработать шапку для сервиса и мы создали ветку feature-2341 от ветки dev (коммит C3 - начало ответвления ветки feature-2341).
В процессе разработки/решения этой задачи в dev другие разработчики сливали другие задачки, образуя новые комиты (C4, C5).
И вот вопрос, каким же образом Git будет сливать в этом случаи ветку feature-2341в dev?
Решение называется трехстороннее слияние потому, что git берёт последние комиты с ветки feature-2341 и dev, и третьим комитом - берёт родительский комит для ветки feature-2341 - С3, по итогу получаем 3 комита, отсюда название.
Дальше git создает новый комит.
Примечание по fast-forward
Если есть желание при слитии веток получить новый комит, как в случаи с трехсторонним слиянием, нужно при использовании команды git merge
дописать флаг —no-ff
git merge stage —no-ff
В таком случаи, git создаст новый комит (merge commit)
Проблема merge
И так, вот мы добрались до кульминационного момента.
Бывает такая потребность, что при merge не хотелось бы получать новый комит.
Решение, на самом деле, есть, но оно заключается в использовании другой команды - rebase.
Git Rebase
Само название, как минимум, может говорить о том, что гит позволяет перебазировать одну ветку в рамках другой ветки.
Представим, что нам нужно обновить ветку feature-2022 до актуального состояния ветки dev.
Для этого мы можем выполнить команду rebase.
Убедимся что мы находимся на ветке feature-2022, далее можно выполнить rebase:
git rebase dev
Механика работы Rebase
После выполнения команды гита - git rebase dev
Git “оторвёт” ветку от изначального ответвляющего комита-родителя C4 и перенесёт-закрепит ответвление в самый конец ветки dev, тем самым в ветке feature-2022 фиксируются все актуальные изменения dev.
Важно понимать!!!
После перебазировки ветки все её комиты изменяют свой hash, это потому, что при “переносе” ветки в конец подливаемой ветки, на самом деле, создаются новые комиты и удаляются старые, от старого родителя.
Поэтому, после Вам следует быть с этим способом обновления ветки очень аккуратными, поскольку меняется (не дополняется, как в случаи merge) история Git, и при командной разработке - может сыграть злую шутку, если не предупреждать команду об обновлении.
Для того, чтобы запушить обновленную ветку, понадобиться использовать флаг -f (force, то есть перезаписать уже имеющиеся комиты в удаленном репозитории).
git push -f origin HEAD
HEAD - символическая ссылка на текущую ветку. На этом подробно останавливаться не будем.
Итого
- Вкратце вспомнили, что такое ветки, комиты
- Рассмотрели возможность и механику команды merge на поверхностном уровне понимания
- Познакомились с Git Rebase, для обновления ветки изменениями другой ветки.
На самом деле, это только вершина вершины айсберга, тот же самый git rebase имеет помимо всего интерактивный режим, можно склеивать несколько комитов, менять комментарий и много другое.
Подписывайтесь на мой профиль в TenChat - дальше больше, я сам в своём роде только углубляюсь в процессы работы Git’а, в том плане, как это работает, на самом деле.
Данная статья послужит неким началом, хоть и не совсем систематически в плане материалы такой темы как Git, но тем не менее, надеюсь, заинтересую.
Буду рад, если найдете очепятки, какие-либо неточности - пишите в комментариях. Всё исправлю, если это будет конструктивно.