Продвинутый Git
1rebase: линейная история← вы здесь2stash: прячем незавершённую работу3reset и revert: отменяем изменения
Урок 1~12 минут

rebase: линейная история

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

Как работает rebase

git rebase main берёт коммиты текущей ветки и переносит их поверх указанной:

До:
main:    C1 → C2 → C3 → C4
                    ↓
feature:           C3 → C5 → C6

После git rebase main (из ветки feature):
main:    C1 → C2 → C3 → C4
                              ↓
feature:                    C5' → C6'

C5' и C6' — новые коммиты (другие хеши, то же содержимое). Старые C5/C6 исчезают из истории feature.

Сравни в симуляции

Переключайся между «merge» и «rebase» — видно разницу в графе:

Зачем это нужно

Чистая история — в проектах с code review легче смотреть diff, если история линейная. Нет лишних merge-коммитов.

Перед merge в main — часто делают git pull --rebase или перебазируют фичу-ветку перед PR, чтобы она начиналась с последнего коммита main.

bash
git switch feature
git rebase main       # переносим feature поверх актуального main
git switch main
git merge feature     # fast-forward, без лишнего merge-коммита

Интерактивный rebase — переписать историю

bash
git rebase -i HEAD~3   # интерактивно редактировать последние 3 коммита

Откроется редактор с коммитами:

pick a3f7c21 feat: авторизация
pick 7c8d9e0 wip: черновик (надо убрать)
pick d4e5f6a fix: опечатка в локе

# Команды:
# pick   = оставить коммит
# reword = изменить сообщение
# squash = слить с предыдущим
# drop   = удалить коммит

Меняешь pick на нужную команду, сохраняешь — Git переписывает историю.

Squash — объединить несколько коммитов в один:

bash
git rebase -i HEAD~4
# Меняешь:
pick abc feat: начал auth
squash def добавил login
squash ghi добавил logout
pick xyz fix: баг
# Результат: 3 коммита превращаются в 2

Конфликты при rebase

Конфликты в rebase решаются так же как при merge — но по одному коммиту:

bash
git rebase main
# CONFLICT: resolve conflicts...
 
# После разрешения:
git add файл
git rebase --continue   # продолжить
 
# Или отменить:
git rebase --abort

Золотое правило

Не перебазируй ветки, которые уже на remote и видны другим.

Rebase создаёт новые хеши коммитов. Если коллеги уже построили работу на старых хешах — у них сломается история.

Безопасно: rebase локальных веток до первого push.
Опасно: rebase ветки после git push.

Команды

bash
git rebase main             # перебазировать на main
git rebase -i HEAD~3        # интерактивный rebase последних 3
git rebase --continue       # продолжить после конфликта
git rebase --abort          # отменить rebase
git pull --rebase           # pull с rebase вместо merge
Золотое правило rebase: никогда не перебазируй ветки, которые уже на remote. Переписываешь историю — ломаешь коллег.
rebase vs merge
f0e1d2init4b5c6dfeat: maina3f7c2fix: main7c8d9efeat: Ad4e5f6feat: Bmainfeature
Ветки разошлись
main и feature оба ушли вперёд от общего предка. Нужно объединить — merge или rebase?
main
feature (оригинал)
rebased commits (C')
🎯
Миссия 1 из 4
Как перебазировать ветку feature поверх main?