Ответ
Обе команды интегрируют изменения из одной ветки в другую, но делают это принципиально разными способами, влияя на историю коммитов.
git merge
- Действие: Создает новый коммит слияния (merge commit), который имеет двух родителей. Этот коммит объединяет историю двух веток.
- История: Сохраняет нелинейную, полную историю разработки (видно ветвление и слияние).
- Безопасность: Не переписывает существующую историю, поэтому безопасна для публичных веток.
# Стандартное слияние feature в main
git checkout main # Переключиться на принимающую ветку
git merge feature # Объединить изменения из ветки feature
git rebase
- Действие: Перемещает (перебазирует) всю цепочку коммитов текущей ветки и «применяет» их поверх указанной ветки. Фактически переписывает историю, создавая новые коммиты с новыми хэшами.
- История: Делает историю линейной, как если бы работа велась последовательно в одной ветке. Убирает видимость параллельной разработки.
- Риск: Переписывает историю, что опасно для коммитов, уже отправленных в общий репозиторий (публичные ветки).
# Перебазирование feature на актуальный main
git checkout feature # Переключиться на ветку, которую перебазируем
git rebase main # «Перемотать» коммиты feature поверх main
Сравнение на диаграмме
До операции (ветка feature ответвилась от main):
A---B---C (main)
D---E (feature)
После git merge:
A---B---C---F (main)
/
D---E (feature)
Коммит F — это merge-коммит, объединяющий C и E.
После git rebase (и последующего fast-forward merge):
A---B---C---D'---E' (main)
Коммиты D' и E' — это новые коммиты с тем же содержанием, что D и E, но примененные поверх C.
Когда что использовать?
- Используйте
merge:- Для слияния публичных веток (например,
featureвmain). - Когда важно сохранить полный контекст и историю слияний.
- Для слияния публичных веток (например,
- Используйте
rebase:- Локально, чтобы поддерживать чистую линейную историю перед слиянием в основную ветку.
- Для обновления своей feature-ветки актуальными изменениями из
main(git rebase main). - Никогда не делайте
rebaseкоммитов, которые уже были отправлены в общий репозиторий.
Ответ 18+ 🔞
А, слушай, история коммитов — это ж как семейное древо, только вместо бабушек и дедушек тут твои кривые правки в коде. И есть два способа скрестить ветки: мердж и ребейз. Разница — как между "давай жить дружно" и "я тут всё перепишу, чтоб красиво было".
git merge — классика, как борщ с пампушками
- Что делает: Создаёт новый, ёбаный, коммит слияния. У этого коммита два родителя, он как мостик между двумя историями.
- История: Всё остаётся, как было. Видно, где ветка отпочковалась, где слилась. Полная картина, хоть и похожая на паутину алкоголика.
- Безопасность: Ничего не переписывает, историю не трогает. Идеально для веток, куда уже кто-то успел посмотреть.
# Делаем по-честному
git checkout main # Переходим на главную ветку
git merge feature # Вливаем фичу со всеми её костылями
git rebase — перфекционист с манией величия
- Что делает: Берёт твою ветку и хуяк — пересаживает её на самый свежий кончик другой ветки. Коммиты физически пересоздаются, у них новые ID. История переписывается, будто ты с самого начала работал на свежей основе.
- История: Получается ровная, линейная полоса, красивая, как стрелка на брюках. Все параллельные разработки стираются из виду.
- Риск: ОПАСНОСТЬ, ПИЗДЕЦ! Если переписал историю, которую уже кто-то забрал к себе — всем придётся страдать. Только для локального гимнастического упражнения.
# Делаем красиво, но только локально!
git checkout feature # Садимся на свою фичу
git rebase main # Аккуратно примастыриваем её коммиты поверх свежего main
Как это выглядит, если нарисовать палкой на песке
Было так (ветка feature уехала в запой от main):
A---B---C (main)
D---E (feature)
Стало после git merge (всех помирили):
A---B---C---F (main)
/
D---E (feature)
Коммит F — тот самый merge-коммит, дипломат и миротворец.
Стало после git rebase (идеальная, но поддельная история):
A---B---C---D'---E' (main)
Коммиты D' и E' — это те же D и E, но уже с новыми паспортами, притворяющиеся, что они всегда шли за C.
Так когда же что юзать, чтобы не вышло конфуза?
-
Жми
mergeбез колебаний, если:- Сливаешь фичу в общую ветку (типа
main). - Хочешь, чтобы в истории остался след, что тут было слияние, а не магия.
- Не хочешь, чтобы тебя убили коллеги.
- Сливаешь фичу в общую ветку (типа
-
Юзай
rebaseосторожно, как сапер, если:- Только локально хочешь причесать свою ветку перед слиянием.
- Нужно обновить свою старую фичу свежими изменениями из
main(перед мерджем). - ЗАПОМНИ, КАК "ОТЧЕ НАШ": Никогда не ребейзь то, что уже ушло в общий репозиторий. Иначе будет ебаный шторм, и виноват будешь ты.