Git и инструменты2 мин чтения

Rebase или merge? Короткая инструкция без священных войн

Обе команды объединяют изменения, но оставляют совсем разную историю. Когда что выбирать, одно золотое правило и как откатить ошибку через reflog.

git

Иллюстративное фото: Unsplash

В каждой команде рано или поздно звучит вопрос: «делаем rebase или merge?». Ответ: и то и другое, просто в разных местах. Обе команды объединяют изменения из двух веток, но оставляют после себя разную историю.

Merge: история такой, какой она была

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

git switch main
git merge feature/login

Rebase: история такой, какой вы хотите её показать

git rebase берёт ваши коммиты и воспроизводит их на новой базе. История линейная и читается как рассказ. Но коммиты получают новые хеши — это новые объекты, даже если изменения те же.

git switch feature/login
git rebase main
# после разрешения конфликта:
git add . && git rebase --continue

Золотое правило: не делайте rebase ветки, на которой работает кто-то кроме вас.

Как совместить на практике

СитуацияВыбор
Обновить свою ветку изменениями из mainrebase
Уборка перед pull requestrebase -i
Влить готовую функцию в mainmerge (или squash)
Ветка, общая для нескольких человекmerge

Две строки конфигурации, которые советую всем: git pull будет делать rebase вместо лишних merge-коммитов, а несохранённые локальные изменения будут автоматически откладываться.

git config --global pull.rebase true
git config --global rebase.autoStash true

Push после rebase

После rebase обычный git push будет отклонён, потому что истории различаются. Вместо --force используйте --force-with-lease: он перезапишет ветку, только если никто тем временем ничего в неё не добавил.

Что-то пошло не так? Reflog

Git почти ничего не теряет. git reflog показывает, где был HEAD перед каждой операцией, поэтому неудачный rebase отменяется одной командой.

git reflog
# a1b2c3d HEAD@{4}: rebase (start): checkout main
git reset --hard HEAD@{5}

Напоследок Спор «rebase или merge» — обычно спор о том, кто читает историю. Договоритесь в команде один раз, запишите в CONTRIBUTING.md и возвращайтесь к работе.

STOS

Блог о фронтенде, DevOps и инструментах

Сделано на WordPress: своя блочная тема, Polylang, Yoast SEO. Посмотреть админку WordPress в Playground ↗

STOS — вымышленный блог, концепт-проект для портфолио. Автор и тексты — примеры.