GIT
#git#reflog#recover#restore#commit#rescue

Восстановление случайно удалённого коммита через reflog

Короткий рецепт восстановления удалённого коммита через git reflog и создание новой ветки.

Как использовать

  1. Выполни git reflog и найди нужный коммит по сообщению или хешу (HEAD@{n} или полный hash).
  2. Безопасно: создай ветку от коммита: git checkout -b recovered-branch <commit-hash>.
  3. В текущую ветку: 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 могут быть удалены — восстановление тогда невозможно.

Проверка

  1. Reflog не пустой — после недавнего reset/rebase выполните git reflog. Должны быть записи HEAD@{0}, HEAD@{1}, … с хешами и сообщениями. Найдите строку с нужным коммитом.

  2. Восстановленная ветка — после git checkout -b recovered-branch <hash> выполните git log -1. Должен отображаться восстановленный коммит. Убедитесь, что это тот коммит (сообщение, файлы).

  3. Файлы из коммита — после 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 в нужную ветку.

Связанные сниппеты: Откат последнего коммита (когда коммит не удалён, а нужно отменить).