Как откатить коммит в Git
29 авг 2023
Что значит откатить коммит?
Во-первых, необходимо понять, что коммит это просто набор патчей
применяемых к файлам в git репозитории. Для примера, пусть у нас
будет файл со следующим содержимым:
// main.c
#include <stdio.h>
int main() {
printf("Hello World!");
return 0;
}
После мы захотели внести изменения в этот файл и сделали новый коммит.
В результате файл стал выглядеть так:
// main.c
#include <stdio.h>
int main() {
printf("Hello Universe!");
return 69;
}
Патч - это разница между двумя этими файлами. Патч для последнего коммита
будет выглядеть примерно так:
// main.c
#include <stdio.h>
int main() {
- printf("Hello World!");
- return 0;
+ printf("Hello Universe!");
+ return 69;
}
Тут указаны какие строчки должны быть удалены и какие строчки должны быть добавлены.
Посмотреть на разницу между двумя коммитами (т.е посмотреть на патч),
можно сделав комманду git diff передав на вход данной команды id/хэш
двух коммитов, которые мы хотим сравнить.
Откатить коммит - это вернуть файл в то же самое состояние, что было до этого коммита. Т.е поменять в патче минусы и плюсы местами. Сделать это можно разными способами. Первое что приходит в голову это сделать все вручную: отредактировать нужные файлы самому и сделать новый коммит сохранив все сделанные изменения. Но данный способ не удобен, т.к коммиты могут содержать очень много изменений во множестве разных файлов. Поэтому git предоставляет специальную команду, которая позволяет автоматизировать данный процесс - git revert
git revert
Команда git revert работает следующим образом.
- На вход подается id/хэш коммита, который нужно откатить. Пускай, для примера, это будет коммит 123abc. В итоге команда выглядит следующим образом - git revert 123abc
- Git автоматом создает новый патч, который содержит откат изменений из коммита 123abc
- Далее, git сохраняет этот патч с откатом, создавая новый коммит
Скорее всего, данную команду придется выполнять для отката последнего
коммита добавленного в мастер. Тот случай, когда происходит мерж коммита
в мастер и деплой. И после деплоя обнаруживается, что этот коммит
внес баг. Для данного случая можно будет просто выполнить команду
git revert HEAD
и затем смержить коммит с откатом в мастер.
Проблем возникнуть не должно. (HEAD - это указатель на id/хэш последнего коммита).
Мы тут не рассматриваем вопрос о том, как баг попал в мастер и почему тесты
перед мержем не отловили его.
Для того чтобы откатить несколько коммитов надо выполнить команду git log и выписать id/хэши коммитов, которые нужно откатить. И затем выполнить команду git revert последовательно для каждого из откатываемых коммитов. Делать откаты надо в обратном хронологическом порядке.