Восстановление случайно удалённого коммита через reflog
Короткий рецепт восстановления удалённого коммита через git reflog и создание новой ветки.
Как использовать
- Выполни git reflog и найди нужный коммит по сообщению или хешу (HEAD@{n} или полный hash).
- Безопасно: создай ветку от коммита: git checkout -b recovered-branch <commit-hash>.
- В текущую ветку: git reset --hard <commit-hash> (осторожно — перезапишет историю). Reflog хранится локально, не пушится.
Коммит пропал после git reset --hard, rebase или удаления ветки — в обычном git log его уже нет. Git хранит ссылки на «последние» коммиты в reflog (локальная история движений HEAD и веток). Проблема: без reflog непонятно, какой хеш был у потерянного коммита; восстановление «наугад» опасно. Симптомы: «коммит исчез», ветка откатилась. Ниже — как найти коммит в reflog и восстановить его в новую ветку или в текущую; что делать после удаления ветки и после hard reset; проверка и ограничения.
Решение
Восстановление случайно удалённого коммита через reflog. Используйте когда коммит удалён через reset, rebase или удаление ветки.
# 1. Просмотр reflog (последние действия)
git reflog
# 2. Поиск по сообщению
git reflog | grep "ваше сообщение коммита"
# 3. Восстановление в новую ветку (безопасно)
git checkout -b recovered-branch <commit-hash>
# 4. Восстановление в текущую ветку (перезаписывает историю)
git reset --hard <commit-hash>
# 5. Восстановить только файлы из коммита
git checkout <commit-hash> -- <file-path>
Полный пример:
git reflog
# abc1234 HEAD@{2}: commit: Important changes
git checkout -b recovered-important-changes abc1234
git checkout main
git merge recovered-important-changes
После удаления ветки:
git reflog | grep "branch-name"
git checkout -b branch-name <commit-hash-from-reflog>
# или: git branch branch-name <commit-hash>
После hard reset:
git reflog
git reset --hard HEAD@{1} # или конкретный хеш из reflog
Reflog хранится локально, по умолчанию около 90 дней. Перед восстановлением в основную ветку создайте ветку от найденного коммита. После git gc --prune=now объекты из reflog могут быть удалены — восстановление тогда невозможно.
Проверка
-
Reflog не пустой — после недавнего reset/rebase выполните
git reflog. Должны быть записи HEAD@{0}, HEAD@{1}, … с хешами и сообщениями. Найдите строку с нужным коммитом. -
Восстановленная ветка — после
git checkout -b recovered-branch <hash>выполнитеgit log -1. Должен отображаться восстановленный коммит. Убедитесь, что это тот коммит (сообщение, файлы). -
Файлы из коммита — после
git checkout <hash> -- path/to/fileфайл в рабочей копии должен соответствовать версии из коммита. Проверьте содержимое и при необходимости закоммитьте.
Типичные ошибки
- Сразу reset —hard в main — можно перезаписать историю и снова «потерять» коммиты. Сначала создайте ветку от найденного хеша, убедитесь, что это нужный коммит, затем merge или reset по необходимости.
- Reflog только локальный — на другом клоне и на сервере этого reflog нет. Восстановленный коммит нужно снова запушить; если ветку удалили на remote, после восстановления создайте ветку и push.
- git gc —prune=now — агрессивная очистка может удалить объекты, на которые ссылается только reflog. Не запускайте prune без необходимости, если есть риск, что коммиты ещё понадобятся.
Где применять
- Локальная разработка: после ошибочного reset, rebase, удаления ветки. На сервере (CI) reflog может быть отключён или очищен — восстанавливать нужно из локального клона.
- Срочное восстановление: сначала reflog, создание ветки от хеша, проверка, затем merge в нужную ветку.
Связанные сниппеты: Откат последнего коммита (когда коммит не удалён, а нужно отменить).