it-swarm.com.ru

Git: "Поврежденный свободный объект"

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

$ 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

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

260
asgerhallas

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

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

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

54
Adam Dymitruk

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

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

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

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

Исправление

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

  1. Создайте резервную копию поврежденного каталога:
    cp -R foo foo-backup
  2. Создайте новый клон удаленного репозитория в новый каталог:
    git clone [email protected]: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 и т. д. работают снова, как и должны.

296
cubic lettuce

Лучше всего, вероятно, просто перекодировать из удаленного репо (т.е. 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  

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

188
user1055643

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

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

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

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

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

gIT версия 1.9.1

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

92
Felipe Pereira

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

Однако, когда я попытался запустить 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 перестал жаловаться.

37
declan

Пытаться

git stash

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

12
Arthur

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

git gc --aggressive --Prune=now

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

4
Jago

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

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

gitk &

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

Вот:

14c0fcc9b3

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

04d44c3298

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

git diff 14c0fcc9b3 04d44c3298 > 1.patch

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

git diff 04d44c3298 fc1d4b0df7 > 2.patch

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

git clone [email protected]: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 без ошибок. Вероятно, в отчете будут строки «висячий коммит» и «висячий блоб», это следствие ваших перебазировок и исправлений в этой папке, и все в порядке. Сборщик мусора удалит их со временем.

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

4
halfer

В ответ @ user1055643 отсутствует последний шаг:

$ rm -fr .git
$ git init
$ git remote add Origin your-git-remote-url
$ git fetch
$ git reset --hard Origin/master
$ git branch --set-upstream-to=Origin/master master  
3
Ertuğrul Altınboğa

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

./objects/x/x

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

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

3
Dez

Я получил эту ошибку после того, как мой (Windows) компьютер решил перезагрузить себя . К счастью, мое удаленное репо было обновлено, поэтому я просто сделал новый git-клон ..

2
Dean Rather

Я следовал за многими другими шагами здесь; Описание Линуса о том, как посмотреть на дерево/объекты git и найти то, чего не хватает, было особенно полезным. Git-Git восстановить поврежденный BLOB

Но, в конце концов, у меня были незакрепленные/поврежденные объекты дерева, вызванные частичным отказом диска, и объекты дерева не так легко восстановить/не охватывать этим документом.

В конце концов, я удалил конфликтующий objects/<ha>/<hash> и использовал git unpack-objects с файлом пакета из достаточно современного клона. Ему удалось восстановить недостающие объекты дерева.

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

2
davenpcj

Я решил следующим образом: Я решил просто скопировать не поврежденный объектный файл из клона резервной копии в мой исходный репозиторий. Это сработало так же хорошо. (Кстати: если вы не можете найти объект в .git/objects/по его имени, он, вероятно, был [упакован] [упакован] для экономии места.)

1
mcginn

Для меня это произошло из-за сбоя питания во время выполнения git Push.

Сообщения выглядели так:

$ git status
error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
fatal: loose object c238824eb3fb602edc2c49fccb535f9e53951c74 (stored in .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74) is corrupt

Я пробовал такие вещи, как git fsck, но это не помогло . Так как сбой произошел во время git Push, он, очевидно, произошел во время перезаписи на стороне клиента, которая происходит после обновления сервера. Я огляделся и понял, что c2388 в моем случае был объектом commit, потому что на него ссылались записи в .git/refs. Поэтому я знал, что смогу найти c2388, когда посмотрю историю (через веб-интерфейс или второй клон).

На втором клоне я сделал git log -n 2 c2388, чтобы определить предшественника c2388. Затем я вручную изменил .git/refs/heads/master и .git/refs/remotes/Origin/master, чтобы он стал предшественником c2388 вместо c2388. Затем я мог сделать git fetch. git fetch несколько раз не срабатывал при конфликтах на пустых объектах. Я удалял каждый из этих пустых объектов, пока git fetch не сработал. Это исцелило хранилище.

1
Christian Hujer

Запуск git stash; git stash pop решил мою проблему

1
Simonluca Landi

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

0
Tyler Gauch

У нас только что был случай здесь. Случилось так, что проблема была в том, что владельцем поврежденного файла был root, а не наш обычный пользователь. Это было вызвано коммитом, сделанным на сервере после того, как кто-то сделал «Sudo su -».

Сначала идентифицируйте ваш поврежденный файл с помощью:

$> git fsck --full

Вы должны получить ответ, подобный этому:

fatal: loose object 11b25a9d10b4144711bf616590e171a76a35c1f9 (stored in .git/objects/11/b25a9d10b4144711bf616590e171a76a35c1f9) is corrupt

Перейдите в папку, где находится поврежденный файл и выполните:

$> ls -la

Проверьте право собственности на поврежденный файл. Если это не так, просто вернитесь в корень вашего репозитория и выполните:

$> Sudo chown -R YOURCORRECTUSER:www-data .git/

Надеюсь, поможет!

0
Thomas Lobjoie

Когда у меня возникла эта проблема, я скопировал свои последние изменения (поскольку я знал, что я изменил), а затем удалил этот файл, на который он жаловался, в .git/location. Затем я сделал git pull. Будьте осторожны, это может не сработать для вас.

0
gareth

У меня просто была такая проблема. Моя конкретная проблема была вызвана сбоем системы, который повредил самый последний коммит (и, следовательно, также главную ветку). Я не толкнул и хотел сделать этот коммит заново. В моем конкретном случае я смог справиться с этим так:

  1. Сделайте резервную копию .git/: rsync -a .git/ git-bak/
  2. Проверьте .git/logs/HEAD и найдите последнюю строку с действительным идентификатором фиксации. Для меня это был второй самый последний коммит. Это было хорошо, потому что у меня все еще были версии файла рабочего каталога, и поэтому каждая версия, которую я хотел.
  3. Сделайте ветку на этом коммите: git branch temp <commit-id>
  4. повторно выполнить битый коммит с файлами в рабочем каталоге.
  5. git reset master temp чтобы переместить основную ветвь на новый коммит, который вы сделали на шаге 2.
  6. git checkout master и убедитесь, что он выглядит правильно с git log.
  7. git branch -d temp.
  8. git fsck --full, и теперь должно быть безопасно удалить любые поврежденные объекты, найденные fsck. 
  9. Если все выглядит хорошо, попробуйте нажать. Если это работает, 

Это сработало для меня. Я подозреваю, что это довольно распространенный сценарий, поскольку наиболее вероятным будет повреждение самого последнего коммита, но если вы потеряете еще один назад, вы, вероятно, все еще можете использовать такой метод, с осторожным использованием git cherrypick и reflog в .git/logs/HEAD.

0
naught101

У меня была такая же проблема в моем голом удаленном репозитории Git. После долгих ошибок я выяснил, что один из моих коллег сделал коммит, в котором некоторые файлы в .git/objects имеют разрешения 440 (r - r -----) вместо 444 (r - r - r). -). После того, как коллега попросил изменить права доступа с помощью «объектов chmod 444 -R» внутри репозитория git, проблема была исправлена.

0
konyak