Git: как вернуть то, что, казалось, потеряно

Инструменты · 21 августа 2026 · ~6 минут

Почти ничего в git не удаляется мгновенно. Коммиты живут в хранилище ещё недели, даже если на них не смотрит ни одна ветка. Главное — не начинать заново, пока не проверены три команды ниже.

Содержание
  1. reflog — главный спасатель
  2. После reset --hard
  3. Detached HEAD
  4. Поиск потерянного коммита
  5. Когда действительно поздно

1. reflog — история всех движений

git reflog
git reflog show feature/login

Это журнал того, куда указывал HEAD: переключения веток, коммиты, ребейзы, слияния. Записи хранятся по умолчанию 90 дней — именно туда уходят «потерянные» коммиты.

a1b2c3d HEAD@{0}: reset: moving to HEAD~3
e4f5a6b HEAD@{1}: commit: add validation
9c8d7e6 HEAD@{2}: commit: fix typo

Строка HEAD@{1} — это не коммит, а ссылка на состояние. Возврат выполняется обычным reset или checkout:

git reset --hard HEAD@{1}

2. Восстановление после reset --hard

Порядок действий, если только что «протёрли» ветку:

git reflog                    # найти нужный HEAD@{n}
git reset --hard HEAD@{n}     # вернуть ветку туда
git status                    # убедиться, что рабочее дерево в порядке

Если нужно вернуть только отдельные файлы, а не всю ветку:

git checkout HEAD@{n} -- src/config.py
Не паникуйте из-за staged-изменений git reset --hard выбрасывает и staged, и unstaged. Но git fsck --lost-found иногда находит брошенные объекты, записанные через git add до сброса.

3. Detached HEAD — коммиты «висят в воздухе

Если вы закоммитили в состоянии detached HEAD и переключились в ветку, коммит остался, но на него не указывает ни одна ветка:

git checkout <SHA>
git branch rescue-work          # даём коммиту имя
git switch rescue-work

Полезная команда — показать, что было в detached-состоянии:

git reflog | grep 'checkout:'

4. Ищем потерянный коммит

git fsck --lost-found --no-reflogs
git log --walk-reflogs --oneline
git log --all --oneline --grep="ключевое слово из сообщения"

git fsck выводит dangling commits — коммиты, до которых не дошли ссылки. Это почти всегда и есть потерянная работа:

git show <SHA из fsck>          # посмотреть, что внутри
git merge <SHA>                  # или git branch temp <SHA>

5. Когда действительно поздно

Есть ситуации, когда git уже не поможет:

Практическая защита: включите в .git/hooks pre-push-проверку для веток main/master и не используйте reset --hard на ветке, которую кто-то ещё может использовать.

Мой рабочий чек-лист при словах «я всё потерял»: git reflog → git fsck --lost-found → git log --all --grep. Если все три молчат — тогда и только тогда начинать заново.