Как работает git merge и какие стратегии слияния существуют
Что проверяют
Понимаете ли вы, что происходит с историей при слиянии, и умеете ли выбрать способ под правила команды. Следом почти всегда спрашивают разницу между merge и rebase и как вы разрешаете конфликт.
Как отвечать
Начните с механики. git merge feature ищет общего предка (merge base) текущей ветки и feature, дальше возможны два исхода:
- fast-forward: если в
mainнет новых коммитов после ответвления, Git просто передвигает указатель вперёд. Коммита слияния нет, история линейная; - трёхстороннее слияние: если обе ветки ушли вперёд, Git сравнивает три снимка (предок и две вершины) и создаёт коммит слияния с двумя родителями. Конфликт возникает, когда обе стороны поменяли одни и те же строки.
Флаги, которые стоит назвать: --no-ff принудительно создаёт коммит слияния, чтобы фича читалась в истории одним блоком; --ff-only откажется сливать, если перемотка невозможна; --squash собирает изменения ветки в один будущий коммит без связи с её историей.
Стратегии в строгом смысле выбираются ключом -s: ort работает по умолчанию начиная с Git 2.34 и отслеживает переименования файлов, recursive в свежих версиях стал его синонимом, octopus сливает сразу несколько веток, ours оставляет дерево текущей ветки, subtree нужен для вложенных проектов. Отдельно есть опции -X ours и -X theirs: они решают в пользу одной стороны только конфликтующие куски.
Свяжите это с работой фронтенд-команды: в GitHub и GitLab кнопка слияния PR предлагает merge commit, squash или rebase, и от выбора зависит, как потом читать историю и откатывать фичу через git revert.
Где спотыкаются
Называют rebase стратегией слияния. Это другая операция: она переписывает коммиты ветки поверх новой базы и меняет их хеши, поэтому общие ветки без договорённости не ребейзят.
Путают опцию -X ours со стратегией -s ours. Первая решает конфликты в свою пользу, вторая молча выбрасывает все изменения другой ветки.
Разрешают конфликт в package-lock.json вручную построчно. Проще разрешить конфликт в package.json, запустить npm install, который сам пересоберёт lock-файл, и проверить diff.