Squash commit как и зачем?

24 марта 2021 г.

Работая с git частенько возникает потребность слить несколько коммитов в один. Тут хочу коротко показать как это сделать и когда это нужно делать.

Проблема

Представим следующую ситуацию, вы создали ветку с master и начали работать над новой функциональностью и в процессе работы в вашей ветке появилось N коммитов:

> git log --pretty=oneline

21b0c8..4e2f New Aaaa
27c9ae..783c Aaaaa2
e525b4..e470 Aaaaaa
3b1af1..b0fa Test
666ebc..a1f6 Fix
3960d2..a9e7 Initialized my first project

Заливать такое содержимое истории в master ветку не совсем корректно для общей истории, да и ваши коллеги не обрадуются увидев такое объяснение изменениям в коммите.

Решение

Лучше всего взять и слить эти изменения в один коммит и уже после пушить на удаленный репозиторий или сливать в master. Для этого мы можем использовать команду rebase:

git rebase -i HEAD~[N]

Где [N] количество коммитов, которые мы хотим слить в месте включая первый. В нашем случае мы хотим слить последние 6 коммитов в один с человеческим комментарием "Initialized my first project".

> git rebase -i HEAD~6

pick 3960de7 Initialized my first project
pick 666ebc6 Fix
pick 3b1af1a Test
pick e525b40 Aaaaaa
pick 27c9aec Aaaaa2
pick 21b0c8f New Aaaa

После выполнение команды будет открыт редактор где нам нужно отредактировать первое слово pick, которое является командой для формирование новой истории коммитов.

Чтобы иметь понимание как можно редактировать pick рассмотрим наиболее используемые команды:

  • pick - команда по умолчанию, указывает на то, что этот коммит будет использоваться в новой истории;
  • reword - позволяет редактировать комментарий коммита;
  • squash - позволяет слить комит с предыдущим;
  • break - позволяет продолжить rebase позже с помощью команды git rebase --continue; Полезно когда вы пытаетесь навести порядок в большой истории коммитов.
  • drop - удаляет комит.

Так как мы хотим слить все наши коммиты в первый, то мы должны отредактировать pick следующим образом:

pick 3960de7 Initialized my first project
squash 666ebc6 Fix
squash 3b1af1a Test
squash e525b40 Aaaaaa
squash 27c9aec Aaaaa2
squash 21b0c8f New Aaaa

После жмем клавишу Esc для того чтобы закончить редактирование, теперь Shift + : и пишем wq чтобы записать (Write) изменения и выйти (Quit).

После этого вас попросят предоставить комментарий, обычно оставляют стандартный, но по желанию можно написать свой для конкретизации причины такого слияния кода.

И опять жмем клавишу Esc, Shift + : и wq. Готово!

> git log --pretty=oneline

3960d2..a9e7 Initialized my first project

Также, если вы используете Github то этот процесс можно сделать проще, и при слиянии вашей ветки используя Pull Requests используйте Squash and merge тогда все ваши коммиты будут слиты в один.

https://api.bcode.dev/v1/content/storage/post/100009/55bc58b8dc9c481482025e18ce81fd47.png