Как откатить коммит в 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 работает следующим образом.

Скорее всего, данную команду придется выполнять для отката последнего коммита добавленного в мастер. Тот случай, когда происходит мерж коммита в мастер и деплой. И после деплоя обнаруживается, что этот коммит внес баг. Для данного случая можно будет просто выполнить команду git revert HEAD и затем смержить коммит с откатом в мастер.Проблем возникнуть не должно. (HEAD - это указатель на id/хэш последнего коммита). Мы тут не рассматриваем вопрос о том, как баг попал в мастер и почему тесты перед мержем не отловили его.

Для того чтобы откатить несколько коммитов надо выполнить команду git log и выписать id/хэши коммитов, которые нужно откатить. И затем выполнить команду git revert последовательно для каждого из откатываемых коммитов. Делать откаты надо в обратном хронологическом порядке.