Восстановление поврежденного Git-репозитория - PullRequest
38 голосов
/ 25 ноября 2011

Мой репозиторий Git был поврежден после нескольких сложных перезагрузок из-за проблем с питанием, и теперь я не могу это исправить (я был в процессе подготовки некоторых файлов при последнем сбое питания):

$ git status
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git fsck
fatal: failed to read object 24377c609184c192f3f3c1733bac7115c1080758: Invalid argument
$ git branch -a
(...works, lists branches...)
$ git checkout someotherbranch
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git log
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git log someotherbranch
(...works, shows commits...)

Итак, как вы можете видеть, моя текущая ветка довольно испорчена, и я, похоже, не могу это исправить.Что я могу попробовать починить?

Ответы [ 9 ]

34 голосов
/ 23 декабря 2011

Мое решение для аналогичной ситуации состояло в том, чтобы заменить хэш поврежденного объекта в .git/refs/heads/my-working-branch на хэш предыдущего коммита (который можно найти в .git/logs/HEAD).

16 голосов
/ 31 октября 2012

Это только что случилось со мной.Я откладываю репозиторий в новую папку и перемещаю свои последние изменения вручную.Низкая технология, но она работает каждый раз.Надеюсь, вы помните свои последние изменения.

9 голосов
/ 03 января 2012

Для меня я включил TRIM в OS X с SSD не от Apple (что не рекомендуется) и, очевидно, вызвал различные повреждения на моем загрузочном диске. Таким образом, испорченный коммит был глубоко в истории.

Меня не слишком заботит восстановление моего репозитория, за исключением того, что у меня есть несколько локальных веток, которые были слишком экспериментальными, чтобы потрудиться перенести их в удаленный репозиторий, и я хотел бы спасти работу в этих ветках.

Теоретически, поскольку это локальный репозиторий, я считаю, что Git должен иметь возможность восстанавливать / восстанавливать себя, используя origin. Почему это невозможно?

Во всяком случае, я наткнулся на эту классную стратегию по переносу ветки в другой локальный репозиторий Git . К сожалению, клонирование репозитория в ../repo_copy с последующим использованием его в качестве локального удаленного устройства привело к следующей ошибке:

! git push --force local_remote HEAD
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument
error: failed to push some refs to '/Users/steve/Dev/repo_copy'

Поэтому я начал с пустого репозитория, а затем вставил в него ветки, и все было в порядке. Так что для любого местного филиала, который у меня был, чей git log не заканчивался:

....
    Fixing cukes
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument

Я бы просто проверил это и затем сделал git push --force local_remote HEAD. Последнее, что я сделал, было:

! cd ~/Dev/repo_copy
! git remote add origin git@github.com:sdhull/my_repo.git  # real remote

Затем я вошел в git config -e и настроил свою основную ветку и снова заработал, ничего не потеряв!

7 голосов
/ 25 ноября 2011

Попробуйте сделать резервную копию хранилища и затем запустить git reset --hard HEAD@{1}, чтобы вернуться к предыдущему HEAD и посмотреть, работает ли это.Это может быть просто текущий HEAD, который поврежден.

(Вы также должны запустить fsck на вашем диске, если вы этого еще не сделали.)

3 голосов
/ 21 апреля 2017

Самое простое решение для меня: вы можете git clone в новой папке, а затем заменить чистую new_folder / .git на старую папку (сломанная папка). У меня это хорошо работает!

git clone ...(remote) new_folder
mv old_folder/.git  old_folder/.git_old
cp -R new_folder/.git  old_folder/
2 голосов
/ 07 июля 2017

Другой альтернативой, которая работала для меня, был сброс заголовка Git и индексации к его предыдущему состоянию, используя:

git reset --keep

Я также попробовал следующие команды, но они не работали для меня, но они могли бы для вас:

git reset --mixed
git fsck --full
git gc --auto
git prune --expire now
git reflog --all
2 голосов
/ 21 сентября 2013

Я смог восстановить свой репозиторий из:

zsh(broken)% git log master
error: object file .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395 is empty
error: object file .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395 is empty
fatal: loose object 7fcab8648a989d9bb3f5246e6be7220395493395 (stored in .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395) is corrupt
zsh(broken)% cat .git/refs/heads/master
7fcab8648a989d9bb3f5246e6be7220395493395
e311726c4eb970f4d4f504ad86248d322855018f da9c14d03e4849394087b61ff6272399937f7cce Nikolay Orliuk <virkony@gmail.com> 1379583764 +0300    commit: plan: timings

Сбрасывая master на предыдущую фиксацию da9c14d03e4849394087b61ff6272399937f7cce, как сообщает @Nash Bridges:

zsh(broken)% echo da9c14d03e4849394087b61ff6272399937f7cce > .git/refs/heads/master
zsh(broken)% git log --oneline -1 master
da9c14d plan: timings
zsh(broken)% git fsck
Checking object directories: 100% (256/256), done.
error: object file .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5 is empty
error: object file .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5 is empty
fatal: loose object 0eace931fdc851da254e9522596d1517d0ed51c5 (stored in .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5) is corrupt

Создание нового пустого хранилища, извлечение master из битого:

zsh(broken)% mkdir ../recover && cd ../recover && git init
Initialized empty Git repository in /home/nikolay/talks/y/recover/.git/
zsh(recover)% git fetch ../broken master
remote: Counting objects: 44, done.
remote: Compressing objects: 100% (44/44), done.
remote: Total 44 (delta 20), reused 0 (delta 0)
Unpacking objects: 100% (44/44), done.
From ../broken
 * branch            master     -> FETCH_HEAD
zsh(recover)% git reset --hard FETCH_HEAD
HEAD is now at da9c14d plan: timings
zsh% git fsck
Checking object directories: 100% (256/256), done.

Чтобы восстановить те изменения, которые были на пути к master:

zsh(recover)% rm -rf * && cp -a ../broken/* ./
zsh(recover)% git add -u && git commit -m 'prepare for publishing'
1 голос
/ 09 сентября 2018

У меня была такая же проблема, и я выполнил следующие шаги, используя git-repair

  • cp myrepo myrepo.bak
  • cd myrepo
  • git repair --force (сначала попробуйте без force)

После успешного завершения дерево вернулось к последнему рабочему коммиту.

Затем я применил meld myrepo myrepo.bak для примененияизменяется из рабочего дерева поврежденного хранилища в исправленное хранилище.

1 голос
/ 10 января 2017

Я следовал инструкциям, найденным в Восстановление из поврежденного хранилища Git :

$ cd /tmp/
$ git clone good-host:/path/to/good-repo
$ cd /home/user/broken-repo
$ echo /tmp/good-repo/.git/objects/ > .git/objects/info/alternates
$ git repack -a -d
$ rm -rf /tmp/good-repo

Это сработало для меня.

...