Отмена изменений в GIT

Опубликовал Максим Баев, 05 мая 2017, 14:10

git-failСлучай, который происходит довольно редко, но метко - это "Ааааа, я накосячил в git!!!". У меня случилось такое сегодня, когда я сделал rebase со squash'ем локальной ветки, не имея этих коммитов в другой ветке. Git не задумываясь слил мои коммиты в один и перенёс его, а мне нужно было сохранить исходную ветку, создав новый squash-коммит.

В общем, здесь я вспомнил про логи и отмену изменений. Git умеет отменять практически любые изменения. Все связанное с передвижением HEAD'а можно отменить reset'ом. В моём случае отмена rebase делается следующим способом...

Смотрим последние изменения (безопасно):

git reflog # для выхода жмем q
# или смотреть последние 10 действий
git reflog -n 10
# или тоже самое, но короче
git reflog -10

Например, мой вывод

$ git reflog -n 6
703952e HEAD@{0}: rebase -i (finish): returning to refs/heads/BPN-3546
703952e HEAD@{1}: rebase -i (squash): BPN-3546 Add content type for Gauge in Drupal
9a23f7e HEAD@{2}: rebase -i (squash): # This is a combination of 2 commits.
c1b984f HEAD@{3}: rebase -i (pick): BPN-3546 Add content type for Gauge in Drupal
c6be61c HEAD@{4}: rebase -i (start): checkout refs/heads/Gauge
cf81cc3 HEAD@{5}: commit (amend): BPN-3546 Add content type for Gauge in Drupal

Дальше находим необходимую точку и откатываем код до её состояния. Здесь я вижу, что последние 5 чекпоинтов связаны с ребейзом. Я их пропускаю и двигаю HEAD назад на 6 изменений.

Здесь нужно понимать, что нельзя отменить какое-то одно, определённое действие совершённое ранее (если оно не последнее в истории). Можно лишь вернуться в фиксированную точку во времени, отменив все действия от текущего момента.
Флаг --hard будет означать, что добавленные изменения будут удалены.
Например, если вы откатываете коммит, в котором добавили файл, то после отката этот файл будет удалён из репозитория.Здесь можно использовать флаг --soft, который означает, что после отката коммита файл останется как не зафиксированные изменения.
git reset --hard HEAD@{5}
# для Windows могут понадобиться кавычки
git reset --hard "HEAD@{5}"

Полезные ссылки

Другие посты