Git: «Поврежденный свободный объект» - PullRequest
274 голосов
/ 23 ноября 2010

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

$ git gc
error: Could not read 3813783126d41a3200b35b6681357c213352ab31
fatal: bad tree object 3813783126d41a3200b35b6681357c213352ab31
error: failed to run repack

Кто-нибудь знает, что с этим делать?

Из файла cat я получаю следующее:

$ git cat-file -t 3813783126d41a3200b35b6681357c213352ab31
error: unable to find 3813783126d41a3200b35b6681357c213352ab31
fatal: git cat-file 3813783126d41a3200b35b6681357c213352ab31: bad file

И из git fsck я получил (не знаю, действительно ли это связано):

$ git fsck
error: inflate: data stream error (invalid distance too far back)
error: corrupt loose object '45ba4ceb93bc812ef20a6630bb27e9e0b33a012a'
fatal: loose object 45ba4ceb93bc812ef20a6630bb27e9e0b33a012a (stored in .git/objects/45/ba4ceb93bc812ef20a6630bb27e9e0b33a012a) is corrupted

Может кто-нибудь помочь мне расшифровать это?

Ответы [ 21 ]

311 голосов
/ 17 декабря 2012

У меня была такая же проблема (не знаю почему).

Это исправление требует доступа к не поврежденной удаленной копии хранилища и сохранит вашу локально работающую копию нетронутой.

Но у него есть некоторые недостатки:

  • Вы потеряете запись всех коммитов, которые не были переданы, и вам придется их повторно подтверждать.
  • Вы потеряетелюбые тайники.

Исправление

Выполните эти команды из родительского каталога над вашим репозиторием (замените 'foo' на имя папки вашего проекта):

  1. Создание резервной копии поврежденного каталога:
    cp -R foo foo-backup
  2. Создание нового клона удаленного репозитория в новый каталог:
    git clone git@www.mydomain.de:foo foo-newclone
  3. Удалениеповрежденный подкаталог .git:
    rm -rf foo/.git
  4. Переместите только что клонированный подкаталог .git в foo:
    mv foo-newclone/.git foo
  5. Удалите оставшуюся часть временного нового клона:
    rm -rf foo-newclone

В Windows вам нужно будет использовать:

  • copy вместо cp -R
  • rmdir /S вместо rm -rf
  • move вместо mv

Теперь foo имеет свой оригинальный подкаталог .git назад,но все локальные изменения все еще там.git status, commit, pull, push и т. Д. Работают снова, как и должны.

197 голосов
/ 14 августа 2013

Ваша лучшая ставка, вероятно, состоит в том, чтобы просто повторно клонировать из удаленного репо (т.е. Github или другой). К сожалению, вы потеряете все невыполненные коммиты и сохраненные изменения, однако ваша рабочая копия должна остаться нетронутой.

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

rm -fr .git
git init
git remote add origin [your-git-remote-url]
git fetch
git reset --mixed origin/master
git branch --set-upstream-to=origin/master master  

Затем зафиксируйте любые измененные файлы, если необходимо.

110 голосов
/ 18 октября 2016

Работая на ВМ, у меня в ноутбуке аккумулятор сдох, получил эту ошибку;

ошибка: объектный файл .git / objects / ce / theRef is empty ошибка: объект файл .git / objects / ce / theRef пустой фатальный: свободный объект theRef (хранится в .git / objects / ce / theRef) поврежден

Мне удалось заставить репо снова работать только с 2 командами и без потери работы (измененные файлы / незафиксированные изменения)

find .git/objects/ -size 0 -exec rm -f {} \;
git fetch origin

После этого я запустил git status, с репо все было в порядке, и произошли мои изменения (ожидая подтверждения, сделайте это сейчас ..).

git version 1.9.1

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

54 голосов
/ 24 ноября 2010

Похоже, у вас есть поврежденный объект дерева.Вам нужно будет получить этот объект от кого-то еще.Надеюсь, у них будет неиспорченная версия.

Вы могли бы восстановить ее, если не можете найти действительную версию от кого-то другого, угадав, какие файлы там должны быть.Возможно, вы захотите узнать, соответствуют ли даты и время объектов.Это могут быть связанные пятна.По этим объектам можно вывести структуру древовидного объекта.

Взгляните на скриншоты Скотта Чакона , касающиеся внутренних элементов git.Это покажет вам, как работает git под капотом и как выполнять эту детективную работу, если вы действительно застряли и не можете получить этот объект от кого-то другого.

39 голосов
/ 06 января 2015

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

Однако, когда я попытался запустить git status, я получил

error: object file .git/objects/xx/12345 is empty
fatal: loose object xx12345 (stored in .git/objects/xx/12345 is corrupt

В отличие от большинства других ответов, я не пытался восстановить какие-либо данные . Мне просто нужно, чтобы Git перестал жаловаться на пустой объектный файл.

Обзор

«Объектный файл» - это хэшированное представление git реального файла, который вас интересует. Git считает, что хэшированная версия some/file.whatever должна храниться в .git/object/xx/12345, и исправление ошибки оказалось главным образом вопросом выяснения, какой файл должен был представлять "свободный объект".

Подробнее

Возможные варианты:

  1. Удалить пустой файл
  2. Получить файл в состоянии, приемлемом для Git

Подход 1: Удалить объектный файл

Первое, что я попробовал, это просто переместить объектный файл

mv .git/objects/xx/12345 ..

Это не сработало - git начал жаловаться на неработающую ссылку. На подходе 2.

Подход 2: исправить файл

У Линуса Торвальдса есть отличная статья о том, как восстановить объектный файл , который решил проблему для меня. Основные шаги суммированы здесь.

$> # Find out which file the blob object refers to
$> git fsck
broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
           to    blob xx12345
missing blob xx12345

$> git ls-tree 2d926
...
10064 blob xx12345  your_file.whatever

Здесь указывается, к какому файлу должен относиться пустой объект. Теперь вы можете починить его.

$> git hash-object -w path/to/your_file.whatever

После этого я проверил .git/objects/xx/12345, он больше не был пустым, и git перестал жаловаться.

12 голосов
/ 29 сентября 2011

Попробуйте

git stash

Это сработало для меня.Он прячет все, что вы не совершали, и это решает проблему.

7 голосов
/ 26 октября 2015

A сборщик мусора исправил мою проблему:

git gc --aggressive --prune=now

Требуется некоторое время для завершения, но каждый свободный объект и / или поврежденный индекс был исправлен.

4 голосов
/ 04 января 2015

Я только что испытал это - моя машина сломалась во время записи в репозиторий Git, и она стала поврежденной. Я исправил это следующим образом.

Я начал с просмотра количества коммитов, которые я не перенес в удаленное репо, таким образом:

gitk &

Если вы не используете этот инструмент, он очень удобен - доступен, насколько мне известно, во всех операционных системах. Это указывало на то, что на моем пульте не было двух коммитов. Поэтому я нажал на метку, указывающую последний удаленный коммит (обычно это будет /remotes/origin/master), чтобы получить хеш (хеш длиной 40 символов, но для краткости я здесь использую 10 - это обычно работает в любом случае).

Вот оно:

14c0fcc9b3

Затем я нажимаю на следующий коммит (т. Е. Первый, которого нет у пульта) и получаю хэш:

04d44c3298

Затем я использую оба из них, чтобы сделать патч для этого коммита:

git diff 14c0fcc9b3 04d44c3298 > 1.patch

Затем я сделал то же самое с другим отсутствующим коммитом, т. Е. Раньше использовал хэш коммита и сам хэш коммита:

git diff 04d44c3298 fc1d4b0df7 > 2.patch

Затем я переместился в новый каталог, клонировал репозиторий с пульта:

git clone git@github.com:username/repo.git

Затем я переместил файлы исправлений в новую папку, применил их и зафиксировал их с точными сообщениями о фиксации (их можно вставить из git log или из окна gitk):

patch -p1 < 1.patch
git commit

patch -p1 < 2.patch
git commit

Это восстановило вещи для меня (и заметьте, что, вероятно, есть более быстрый способ сделать это для большого количества коммитов). Однако мне было интересно посмотреть, можно ли отремонтировать дерево в поврежденном репо, и ответ - можно. С восстановленным репо, доступным, как указано выше, выполните эту команду в сломанной папке:

git fsck 

Вы получите что-то вроде этого:

error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d

Чтобы сделать ремонт, я бы сделал это в сломанной папке:

rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d

т.е. удалите поврежденный файл и замените его хорошим. Возможно, вам придется сделать это несколько раз. Наконец, наступит момент, когда вы сможете запустить fsck без ошибок. Вероятно, в отчете будут строки «висячий коммит» и «висячий блоб», они являются следствием ваших перебазировок и исправлений в этой папке, и все в порядке. Сборщик мусора удалит их со временем.

Таким образом (по крайней мере, в моем случае) поврежденное дерево не означает, что невыдвинутые коммиты будут потеряны.

3 голосов
/ 21 июля 2015

Я также получил ошибку поврежденного незакрепленного объекта.

./objects/x/x

Я успешно исправил ее, войдя в каталог поврежденного объекта.Я видел, что пользователи, назначенные этому объекту, были , а не мой пользователь git.Я не знаю, как это произошло, но я запустил chown git:git для этого файла, а затем он снова заработал.

Это может быть потенциальным решением проблем некоторых людей, но не обязательно всех их.

2 голосов
/ 18 октября 2018

просто запуск git prune исправил эту проблему для меня

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...