Git·19 вопросов

Как восстановить удалённый коммит или ветку в Git?

Ответ

В Git почти ничего не удаляется безвозвратно. Даже после reset --hard или удаления ветки, коммиты остаются в reflog и могут быть восстановлены в течение 90 дней.

git reflog — главный инструмент восстановления. Reflog записывает каждое перемещение HEAD: коммиты, checkout, reset, pull. Выполните git reflog — увидите историю с хэшами коммитов и описаниями действий. Найдите хэш коммита до удаления. Запись вида "a1b2c3d HEAD@{2}: reset: moving to HEAD~1" означает, что на HEAD@{3} был коммит, который вы сбросили.

Восстановление коммита: git reset --hard <hash> перемещает текущую ветку к указанному коммиту. Если не хотите переписывать текущую ветку, создайте новую: git branch recovered <hash>, затем git checkout recovered.

Восстановление удалённой ветки: git reflog покажет последний коммит ветки. Найдите запись вида "abc1234 branchname@{1}: commit: last commit". Выполните git branch branchname <hash> — ветка восстановится с этим коммитом как HEAD.

Восстановление после git reset --hard: если вы случайно сделали reset --hard и потеряли изменения, git reflog покажет предыдущее состояние HEAD. Найдите хэш до reset и выполните git reset --hard <hash>. Изменения вернутся.

Восстановление после force-push: если кто-то сделал force-push и затёр ваши коммиты в remote, коммиты всё ещё есть в вашем локальном reflog. Найдите хэш через git reflog, создайте ветку git branch backup <hash>, затем git push origin backup. Коммиты снова в remote.

Восстановление uncommitted изменений: если вы сделали git stash drop и потеряли stash, git fsck --no-reflog --unreachable покажет dangling-объекты. Найдите commit-объект с изменениями вашего stash: git fsck --no-reflog --unreachable | grep commit. Затем git stash apply <hash> восстановит stash.

Сроки: reflog хранит записи 90 дней для reachable-коммитов и 30 дней для unreachable. После этого Git удаляет объекты через git gc. Если прошло больше 90 дней — восстановление невозможно. Поэтому проверяйте reflog сразу после случайного удаления.

Профилактика: перед reset --hard или force-push создавайте backup-ветку: git branch backup-$(date +%s). Это занимает секунду и спасает от потери работы.

Полезен ли этот ответ?

Другие вопросы этой темы

Связанные вопросы из других тем