210 слов | 1 минута
Откат коммитов в Git
Инструкция для ситуации, когда в ветку попали «плохие» коммиты: как безопасно откатиться, найти нужное состояние кода и при необходимости перенести отдельные изменения через cherry-pick.
Сценарий
В ветке main появились три «плохих» коммита (последние 3). Нужно откатиться на 4 шага назад, проверить исчезновение ошибки, внести правки и снова запушить.
Шаг 1 — Сохранить текущую работу
Если есть незакоммиченные изменения — сохраните их в stash:
git stash push -m "WIP before rollback"
Шаг 2 — Посмотреть историю коммитов
git log --oneline --decorate --graph -n 10
Пример вывода:
* a1b2c3d (HEAD -> main, origin/main) Fix wrong validation
* d4e5f6g Add logging
* h7i8j9k Refactor auth flow
* l0m1n2o Implement new feature
* p3q4r5s Update README
a1b2c3d — текущий HEAD. Нужный коммит (4 назад) — l0m1n2o.
Шаг 3 — Получить хэш нужного коммита
git rev-parse HEAD~4
Пример вывода:
l0m1n2o9abcdef1234567890abcdef123456
Шаг 4 — Откатиться локально
git reset --hard HEAD~4
Пример вывода:
HEAD is now at l0m1n2o Implement new feature
После этого файлы находятся в состоянии коммита HEAD~4.
Шаг 5 — Проверить проект
Запустите тесты или воспроизведите сценарий с ошибкой. Если ошибка исчезла — переходите к следующему шагу. Если нет — повторите откат ещё на несколько коммитов.
Шаг 6 — Просмотреть «потерянные» коммиты через reflog
Даже после reset --hard коммиты остаются доступными:
git reflog
Пример вывода:
e1f2a3b (HEAD -> main) HEAD@{0}: reset: moving to HEAD~4
a1b2c3d HEAD@{1}: commit: Fix wrong validation
d4e5f6g HEAD@{2}: commit: Add logging
h7i8j9k HEAD@{3}: commit: Refactor auth flow
HEAD@{1..3} — «потерянные» коммиты.
Шаг 7 — Просмотреть содержимое коммита
git show a1b2c3d
Пример вывода:
commit a1b2c3d4e5f67890...
Author: Dmitry <dmitry@example.com>
Date: Fri Nov 28 15:10:00 2025 +0300
Fix wrong validation
diff --git a/src/auth.js b/src/auth.js
index 1234567..89abcde 100644
--- a/src/auth.js
+++ b/src/auth.js
@@ -45,7 +45,7 @@ function validate(user) {
- if (user.password.length < 6) return false;
+ if (user.password.length < 8) return false;
}
Шаг 8 — Восстановить коммит в отдельную ветку
Если нужно извлечь изменения из «потерянного» коммита:
git checkout -b recover-a1b2c3d a1b2c3d
Шаг 9 — Перенести нужные изменения через cherry-pick
git checkout main
git cherry-pick a1b2c3d
Пример успешного вывода:
[main 9f8e7d6] Fix wrong validation
Date: Fri Nov 28 15:10:00 2025 +0300
1 file changed, 1 insertion(+), 1 deletion(-)
При конфликтах Git укажет, какие файлы нужно исправить вручную.
Шаг 10 — Запушить изменения
После изменения истории через reset --hard потребуется force push:
git push --force origin main
Пример вывода:
To github.com:your/repo.git
+ a1b2c3d... l0m1n2o HEAD -> main (forced update)
Безопасный откат без изменения истории: git revert
Если другие разработчики уже синхронизировались с веткой — не переписывайте историю. Используйте revert:
git revert a1b2c3d..HEAD
git push origin main
git revert создаёт новые коммиты, отменяющие изменения, без удаления существующих.
Краткая шпаргалка
git log --oneline
git rev-parse HEAD~4
git reset --hard HEAD~4
# исправить ошибку, закоммитить
git add .
git commit -m "исправляет ошибку после отката"
git push --force
# при необходимости найти старые коммиты:
git reflog
git show <hash>
Дополнительные команды:
# проверить текущее состояние
git status
# экспериментировать безопасно в отдельной ветке
git checkout -b try-rollback
git reset --hard HEAD~4
# восстановить сохранённые изменения из stash
git stash list
git stash apply stash@{0}