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). Це займає секунду і рятує від втрати роботи.

Чи корисна ця відповідь?

Інші питання цієї теми

Пов’язані питання з інших тем