Git: объединение коммитов (Squash)
Последнее обновление
Squash объединяет несколько коммитов в один, так что беспорядочная череда коммитов "wip", "исправил опечатку", "вот теперь точно исправил" превращается в один чистый коммит. Обычный инструмент - интерактивный rebase - git rebase -i - где ты помечаешь коммиты для объединения. Поскольку squash переписывает историю, делай это до push или в ветке, над которой работаешь только ты.
Попробуй эти команды в терминальном playground - настоящая оболочка в твоём браузере, ничего устанавливать не нужно.
Синтаксис
| Command | What it does |
|---|---|
git rebase -i HEAD~3 | Интерактивный rebase последних 3 коммитов |
git rebase -i main | Rebase каждого коммита, начиная с main |
git merge --squash feature | Объединяет коммиты ветки в один при слиянии |
git reset --soft HEAD~3 && git commit | Объединяет последние 3 коммита без rebase |
Команды интерактивного rebase
В открывшемся редакторе замени pick на одну из этих.
| Keyword | What it does |
|---|---|
pick | Оставляет коммит без изменений |
squash (s) | Сливает с предыдущим коммитом, объединяет сообщения |
fixup (f) | Сливает, но отбрасывает сообщение этого коммита |
reword (r) | Оставляет коммит, но редактирует его сообщение |
Разбор примера
Объедини последние три коммита в один перед push.
| Step | Action | Result |
|---|---|---|
| 1 | git rebase -i HEAD~3 | Открывает последние 3 коммита в редакторе |
| 2 | Установи для коммитов 2 и 3 значение squash | Помечает их для слияния с первым |
| 3 | Сохрани и отредактируй объединённое сообщение | Три коммита становятся одним чистым коммитом |
Часто задаваемые вопросы об объединении коммитов в Git
Как объединить последние N коммитов в Git?
git rebase -i HEAD~N (например, HEAD~3 для последних трёх). В редакторе оставь первый коммит как pick, а остальные измени на squash (или fixup, чтобы отбросить их сообщения). Сохрани, отредактируй объединённое сообщение коммита, и коммиты сольются в один.В чём разница между squash и fixup?
squash сохраняет сообщение коммита и позволяет объединить его с остальными в редакторе. fixup полностью отбрасывает сообщение коммита, оставляя только сообщение более раннего коммита - удобно для коммитов "упс, мелкая правка", которые не нужны в итоговом сообщении.Как объединить всю ветку при слиянии?
git merge --squash feature, затем git commit. Это применяет все изменения ветки как проиндексированные (staged) и позволяет записать их одним коммитом в целевой ветке, не перенося отдельные коммиты ветки. Кнопка "Squash and merge" в GitHub делает то же самое.Можно ли объединить коммиты без интерактивного rebase?
git reset --soft HEAD~N откатывает ветку на N коммитов назад, сохраняя все их изменения проиндексированными (staged), а затем один git commit записывает их как один. Это быстрый способ объединить самые свежие коммиты, не открывая редактор rebase.