Git rebase vs merge: рабочий процесс
Merge vs Rebase
git merge создаёт merge-коммит, сохраняя историю ветки нетронутой. git rebase переписывает коммиты поверх целевой ветки, создавая линейную историю. Оба инструмента имеют свои преимущества и недостатки.
Merge: сохранение контекста
# Переключиться на ветку фичи
git checkout feature/login
# Слить с main
git merge main
# Результат:
# * Merge branch 'main' into feature/login (merge commit)
# |\
# | * Add rate limiting
# | * Fix typo in README
# * | Implement OAuth
# |/
# * Initial commit
Преимущества merge: безопасно для публичных веток, сохраняет контекст того, когда и почему ветки были объединены. Недостаток: линейная история засоряется merge-коммитами.
Rebase: чистая история
# Переключиться на ветку фичи
git checkout feature/login
# Переписать коммиты поверх main
git rebase main
# Результат:
# * Fix typo in README
# * Add rate limiting
# * Implement OAuth
# * Initial commit
Преимущества rebase: линейная история, leichtere Review. Недостаток: переписывает историю, опасно для публичных веток.
Рабочий процесс с rebase
# 1. Регулярно обновляйте feature-ветку
git checkout feature/login
git fetch origin
git rebase origin/main
# 2. Решайте конфликты по мере появления
git rebase --continue
# или
git rebase --abort
# 3. Когда фича готова — fast-forward merge
git checkout main
git merge feature/login
# 4. Удалите feature-ветку
git branch -d feature/login
git push origin --delete feature/login
Interactive rebase
Позволяет редактировать, объединять и переупорядочивать коммиты:
# Редактировать последние 5 коммитов
git rebase -i HEAD~5
# Откроется редактор:
pick abc1234 Add user model
pick def5678 Fix typo in model
pick ghi9012 Add validation
pick jkl3456 WIP: working on tests
pick mno7890 Add tests
# Преобразования:
pick abc1234 Add user model
squash def5678 Fix typo in model
pick ghi9012 Add validation
drop jkl3456 WIP: working on tests
pick mno7890 Add tests
Никогда не делайте rebase на публичных ветках (main, develop). Rebase переписывает хеши коммитов, что сломает работу у всех, кто уже клонировал репозиторий.
Cherry-pick
# Применить конкретный коммит на текущую ветку
git cherry-pick abc1234
# Применить диапазон коммитов
git cherry-pick abc1234..def5678
# Применить без автоматического коммита (оставит staged)
git cherry-pick --no-commit abc1234
CI/CD интеграция
В CI-пайплайнах rebase помогает:
# .github/workflows/pr.yml
name: PR Validation
on:
pull_request:
branches: [main]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: git rebase origin/main
- run: make test
- run: make lint
Проверка rebase в CI ловит конфликты до мержа. Если rebase не удался — CI упадёт и разработчик исправит конфликты локально.
Git rerere
# Включить rerere (reuse recorded resolution)
git config --global rerere.enabled true
# Теперь Git будет запоминать решения конфликтов
# и автоматически применять их при повторном появлении
Правила команды
- Feature-ветки: rebase на main перед PR
- Release-ветки: merge с main
- Hotfix-ветки: cherry-pick нужных коммитов
- Публичные ветки: никогда не rebase
- Перед rebase сделайте
git pull --rebaseвместоgit pull
Вывод
Rebase для feature-веток, merge для интеграции. Этот баланс даёт чистую историю и безопасность. Настройте pull.rebase = true в gitconfig, чтобы избежать ненужных merge-коммитов при обновлении.