11 слов | 1 минута

Откатиться на несколько коммитов назад в Git

Ниже — пошаговый путь решения ситуации: у вас появились плохие коммиты; вы хотите откатиться на N коммитов назад, проверить, внести правки и снова запушить. Включены примерные выводы команд, чтобы было проще понять, что именно вы увидите в терминале.

Сценарий

Предположим, в ветке main появились три «плохих» коммита (последние 3). Вы хотите откатиться на 4 шага назад, проверить, что ошибка исчезла, внести правки и снова запушить.

Шаг 0 — Сохранить текущую работу (рекомендуется)

Если у вас есть незакоммиченные изменения — сохраните их:

git stash push -m "WIP before rollback"

Шаг 1 — Посмотреть историю коммитов

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).

Шаг 2 — Получить хэш нужного коммита (можно через HEAD~4)

git rev-parse HEAD~4

Пример вывода:

l0m1n2o9abcdef1234567890abcdef123456

Шаг 3 — Откатиться на нужный коммит локально

Если вы уверены, что хотите изменить состояние рабочей копии и историю локально:

git reset --hard HEAD~4

Пример вывода (обычно без подробностей):

HEAD is now at l0m1n2o Implement new feature

После этого ваши файлы — в состоянии коммита HEAD~4.

Шаг 4 — Проверить проект, найти ошибку

Запустите тесты, приложение, или воспроизведите сценарий, где была ошибка.

Если ошибка исчезла — отлично. Если осталась — можно откатиться ещё дальше (см. ниже).

Шаг 5 — Если нужно, посмотреть "потерянные" коммиты через 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} находятся «потерянные» коммиты.

Шаг 6 — Посмотреть, что было в этих коммитах (git show)

Чтобы увидеть содержимое коммита и diff:

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;
 }

Вы увидите метаданные (author, date, message) и сам diff.

Шаг 7 — Восстановить один из потерянных коммитов в отдельную ветку (если нужно)

Если вы хотите извлечь изменения из потерянного коммита:

git checkout -b recover-a1b2c3d a1b2c3d

Теперь у вас есть ветка recover-a1b2c3d с тем состоянием кода из этого коммита.

Шаг 8 — Перенести нужные изменения в текущую ветку

Можно сделать cherry-pick нужного коммита(ов):

git checkout main
git cherry-pick a1b2c3d

Пример вывода cherry-pick (успешного):

[main 9f8e7d6] Fix wrong validation
 Date: Fri Nov 28 15:10:00 2025 +0300
 1 file changed, 1 insertion(+), 1 deletion(-)

Если cherry-pick вызывает конфликты — Git подскажет, какие файлы надо править.

Шаг 9 — Когда всё готово, запушить изменения в удалённый репозиторий

Если вы изменяли историю (git reset --hard) и хотите, чтобы удалённый репозиторий принял новую историю — нужен force push:

git push --force origin main

Пример вывода:

To github.com:your/repo.git
 + a1b2c3d... l0m1n2o HEAD -> main (forced update)

Безопасная альтернатива — не переписывать историю: git revert

Если нельзя менять историю (например, другие люди уже синхронизировались), вместо reset используйте revert:

git revert a1b2c3d..HEAD
git push origin main

git revert создаст новые коммиты, отменяющие изменения «плохих» коммитов.

Дополнительные советы и полезные команды

  • Посмотреть текущее состояние:

    git status
    

    Пример:

    On branch main
    Your branch is up to date with 'origin/main'.
    nothing to commit, working tree clean
    
  • Если хотите экспериментировать — создавайте временную ветку и работайте там:

    git checkout -b try-rollback
    git reset --hard HEAD~4
    
  • Если потеряли незакоммиченные изменения и ранее делали git stash, восстановить:

    git stash list
    git stash apply stash@{0}
    

Краткая итоговая последовательность (быстрая шпаргалка)

git log --oneline
git rev-parse HEAD~4
git reset --hard HEAD~4
# проверить проект, исправить, закоммитить
git add .
git commit -m "Fix after rollback"
git push --force
# при необходимости посмотреть старые коммиты:
git reflog
git show <hash>