Gymterview
middle

Merge vs Rebase в контексте CI — что предпочтительнее?

Merge и Rebase — два способа интеграции изменений из одной ветки в другую, каждый из которых по-разному влияет на историю коммитов и процесс CI.

Представьте, что вы ведёте дневник. Merge — это когда вы вклеиваете чужие записи в свой дневник отдельным вложением с пометкой «получено от коллеги 15 мая». Rebase — это когда вы переписываете чужие записи своим почерком так, будто они всегда были частью вашего дневника. Результат один — информация есть, но история выглядит по-разному.

Merge (слияние)

Пример
git checkout main
git merge feature/my-feature
  • Создаёт merge-коммит, сохраняя полную историю ветвления.
  • История нелинейная — видно, когда ветка была создана и влита.
  • Не изменяет существующие коммиты (безопасно).

Rebase (перебазирование)

Пример
git checkout feature/my-feature
git rebase main
git checkout main
git merge feature/my-feature  # fast-forward
  • Переносит коммиты ветки на вершину целевой ветки.
  • Создаёт линейную историю.
  • Изменяет хеши коммитов (переписывает историю).

Влияние на CI

Аспект Merge Rebase
CI-статус Merge-коммит проверен CI Каждый перебазированный коммит должен собираться
Конфликты Разрешаются один раз в merge-коммите Разрешаются для каждого коммита при rebase
Повторный запуск CI Только для merge-коммита Для всех перебазированных коммитов (новые хеши)
Bisect (поиск бага) Сложнее из-за нелинейной истории Проще — линейная история
Force push Не нужен Нужен в feature-ветку после rebase
Аудит Сохраняет полный контекст (кто, когда, откуда) Линейная история, меньше контекста

Рекомендации

  • Для feature-веток: git rebase main перед merge — обеспечивает актуальность ветки и проверяет, что ваши изменения совместимы с последней версией main.
  • Для интеграции в main: merge (или squash merge) — сохраняет точку интеграции.
  • Никогда не rebase публичные ветки (main, develop) — это переписывает историю для всех участников и ломает CI.

Типичный workflow с CI

  1. Разработчик работает в feature/ABC-123.
  2. Перед merge в main: git rebase main (актуализация).
  3. Push (возможно, force push в feature-ветку) и создание Pull Request.
  4. CI проверяет ветку.
  5. Code review.
  6. Merge (или squash merge) в main.
  7. CI проверяет main.

Squash Merge — компромисс

Пример
git merge --squash feature/my-feature
git commit -m "FEAT-123: описание функциональности"

Все коммиты feature-ветки объединяются в один коммит при merge. Результат:

  • Линейная история в main.
  • Каждый коммит в main — завершённая функциональность.
  • Упрощает аудит и bisect.
  • Теряется детальная история работы в feature-ветке.

Вывод

Нет единственно правильного ответа — выбор зависит от контекста. В банковской среде часто используют squash merge — это даёт линейную историю, удобную для аудита, и каждый коммит в main соответствует конкретной задаче.

На собеседовании: покажите, что вы понимаете trade-off. Merge сохраняет историю, rebase делает её линейной. Для CI ключевое — rebase помогает до merge (актуализация ветки), а merge (или squash merge) — при интеграции в main. Никогда не rebase публичные ветки.