Как объединить много коммитов в один в IDE?
Что проверяют
Понимаете ли вы, что происходит с историей Git при объединении коммитов, а не только где кнопка в IntelliJ IDEA. Следом почти всегда спрашивают, что делать, если коммиты уже запушены, и чем squash отличается от fixup.
Как отвечать
Назовите способ в IDE и эквивалент в консоли:
- IntelliJ IDEA, вкладка Log: в окне Git выделите несколько идущих подряд коммитов текущей ветки, в контекстном меню выберите «Squash Commits…» и отредактируйте итоговое сообщение;
- интерактивный rebase в IDE: «Interactively Rebase from Here…» на коммите открывает диалог, где каждому коммиту задаётся действие: pick, squash, fixup, reword, drop, плюс можно менять порядок;
- консоль:
git rebase -i HEAD~3, у всех строк кроме первойpickменяется наsquashилиfixup. Squash склеивает сообщения, fixup оставляет только сообщение первого коммита; - быстрый вариант:
git reset --soft HEAD~3и один новыйgit commit. Изменения остаются в индексе, история сжимается в один коммит; - autosquash:
git commit --fixup <sha>по ходу работы, потомgit rebase -i --autosquashсам расставит fixup; - при слиянии:
git merge --squashили кнопка «Squash and merge» в GitHub и GitLab, если в команде так принято.
Главное правило: переписывать можно только свою ветку. Если коммиты уже на сервере, после rebase нужен git push --force-with-lease, а не --force: он откажется перезаписывать чужие коммиты, появившиеся на сервере после вашего последнего fetch.
Где спотыкаются
Сжимают коммиты в общей ветке вроде main или develop. У коллег история расходится, и начинаются дубли и конфликты.
Не знают, как откатиться. Незавершённый rebase прерывается git rebase --abort, а после завершённого старое состояние находится через git reflog.
Не учитывают, что squash меняет хэши. Ссылки на старые коммиты в задачах и ревью перестают работать, а ветки, отведённые от старых коммитов, придётся перебазировать.