среда, 17 февраля 2016 г.

Git. Исправления "задним числом"

Нередко бывает, что нужно исправить какой-то коммит.
(Примечание: Исправлять что-либо можно только то, что вы еще не успели запушить, иначе проблемы возникнут уже не у вас, а у ваших коллег.)

1. Чаще всего, вы замечаете, что что-то забыли сразу же после того как только что сделали коммит. Этот случай самый простой.

Доделайте то что нужно (не забудьте проиндексировать изменения git add ...), а затем выполните:
git commit --amend
Эта команда заставит git переделать последний коммит.
При этом также появится редактор для редактирования комментария. Если изменять комментарий не нужно, добавьте --no-edit.
Также можно добавить параметр --all, что автоматом внесет в индекс все модифицированные файлы (но пропустит новые и удаленные).
В самом распространенном случае команда для переделки последнего коммита выглядит как:
git commit --amend --all --no-edit

2. Если же вам необходимо изменить более ранний коммит (предпоследний и т.д.), то на помощь придет команда:
git rebase -i abc123^
где вместо abc123 подставьте хэш коммита, который вы хотите отредактировать (не забудьте поставить ^ после хэша).
(В качестве хэша коммита также работает и HEAD~n, где вместо n можно указать какой по счету коммит (считая от последнего в текущей ветке) вы хотите изменить.)
Появится редактор со списком коммитов, где первой строчкой будет
pick abc123 Blah-blah-blah comment
(Blah-blah-blah comment - это комментарий коммита)
Замените pick на edit, сохраните и выйдите из редактора. Git откатит ваш рабочий каталог до состояния, когда коммит abc123 был только что сделан.
Далее действуем как в п.1, т.е. делаете то, что вам нужно и когда закончили делаете git add ... и git commit --amend (впрочем, последняя команда не обязательна, но без нее git предложит отредактировать вам комментарий для только что переделанного коммита).
Но можно сделать и отдельный дополнительный коммит или даже несколько.
Затем пишем:
git rebase --continue
При этом внимательно читаем выводимые сообщения. Если вы затронули строки, которые также были изменены в последующих коммитах, то возможны конфликты. В этом случае нужно разрешить возникшие конфликты и снова сделать
git rebase --continue
Повторять до полного оргазма успеха.

Если вы запутались или из-за высыпавшегося количества конфликтов решили, что лучше оставить все как было, то пишем:
git rebase --abort
Все вернется в состояние как в самом начале (перед первым git rebase).

В редакторе со списком коммитов можно делать и более интересные вещи (в нем есть маленькая подсказка). Например, изменить порядок коммитов (но это, опять же, чревато конфликтами) или слить несколько коммитов в один.

Комментариев нет:

Отправить комментарий