Что такое Git Rebase
Итак, git работает с комитами. Каждый комит — набор изменений. У каждого комита есть уникальный hash. Когда происходит слияние веток посредством merge:
$ git merge "another_branch"
то все комиты сохраняются: сохраняются комментарии комита, его hash, плюс, как правило, добавляется еще один искусственный комит. При этом комиты могут чередоваться друг с другом. Это не всегда удобно. Допустим, ваш комит решили откатить — выискивать в общем списке где ваш комит, а где не ваш - не очень приятно. И вообще, в общей истории хочется видеть действительно важные изменения, а не «ой, я забыл поставить ;». Для того, чтобы несколько комитов склеивать в один можно использовать rebase. Хотя в интерфейсе GitHub есть кнопочка squash & commit — это когда вы создаете pull request (PR) из одной ветки в другую (как правило из вашей рабочей ветки в основную) и после прохождения всех формальностей можно нажать squash & commit, обновить комментарий и ваши изменения появятся в основной ветке как один комит.
Хочу написать о двух случаях использования rebase:
- Когда изменения включаются из одну ветку в другую не посредством merge, а посредством rebase:
$ git rebase "another_branch"
- Когда можно руками отредактировать несколько ваших комитов — например склеить их, изменить коментарий:
$ git rebase -i {HEAD~_commit_count_|commit_hash}
Итак, вы все сделали в своей уютненькой веточке, и решили поделиться этим комитом с миром, но мир хочет от вас только один комит.
git rebase -i
запустит редактор и предложит отредактировать комиты (порядок следования комитов — сверху вниз в отличие от git log). Можно оставить комит как есть, можно изменить комментарий, можно склеить с предыдущим. Как правило, ваш первый комит надо оставить как есть, а все остальные изменить на
pick "commit_hash" "comment" → fixup "commit_hash" "comment".
При этом все комментарии, которые были в fixup комитах потеряются и будет использоваться комментарий от первого комита. Если вам были дороги комментарии, то стоит использовать squash вместо fixup.
Но если процесс разработки был долог, то скорее всего вам приходилось делать merge основной ветки. И все ваши комиты перемешаются с общими комитами и склеивать ваши с не вашими будет задачей непростой. Поэтому перед тем, как делать
git rebase -i <>
стоит сделать
git rebase
Он поставит все ваши комиты в конец списка всех комитов (в чем можно убедиться запустив git log
) и после этого запустить
git rebase -i <HEAD~Количесво_ваших_комитов>
во всех строчках кроме первой заменить pick → {fixup|squash} и вуаля — у вас один комит.
Если в процессе редактирования комитов git rebase -i <>
вы как-то накосячили, то не стоит жать Control+C. Exit code выхода из редактора git не волнует. Он просто возьмет файл и сделает все по нему. Просто удалите или закомментируйте все строчки в файле. Git поймет, что вы ничего не хотели.
После манипуляций с rebase потребуется push с опцией -F. Все это потому, что мы переписываем меняем историю комитов и git нас об этом честно предупреждает.
$ git push -f
Oct. 8, 2023, Источник
git merge
- принимает содержимое ветки источника и объединяет их с целевой веткой. В этом процессе изменяется только целевая ветка. История исходных веток остается неизменной. git rebase
— еще один способ перенести изменения из одной ветки в другую. Rebase сжимает все изменения в один «патч». Затем он интегрирует патч в целевую ветку. В отличие от слияния, перемещение перезаписывает историю, потому что она передает завершенную работу из одной ветки в другую. В процессе устраняется нежелательная история.
Oct. 8, 2023, Источник