Git: “Objeto solto corrompido”

Sempre que eu pego do meu controle remoto, recebo o seguinte erro sobre a compactação. Quando executo a compression manual, obtenho o mesmo:

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

Alguém sabe o que fazer sobre isso?

De cat-arquivo eu recebo isso:

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

E do git fsck eu entendo isso (não sei se é realmente relacionado):

 $ 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 

Alguém pode me ajudar a decifrar isso?

Parece que você tem um object de tree corrompido. Você precisará obter esse object de outra pessoa. Espero que eles tenham uma versão não corrompida.

Você pode realmente reconstruí-lo se não conseguir encontrar uma versão válida de outra pessoa, adivinhando quais arquivos devem estar lá. Você pode querer ver se as datas e horas dos objects correspondem a ele. Essas podem ser as bolhas relacionadas. Você pode inferir a estrutura do object da tree a partir desses objects.

Dê uma olhada nos screencasts de Scott Chacon sobre git internals. Isso mostrará como o git funciona e como fazer esse trabalho de detetive se você estiver realmente preso e não puder obter esse object de outra pessoa.

Eu tive o mesmo problema (não sei porque).

Essa correção requer access a uma cópia remota não corrompida do repository e manterá sua cópia local em funcionamento intacta.

Mas tem algumas desvantagens:

  • Você perderá o registro de quaisquer commits que não foram enviados e terá que recomeçá-los.
  • Você perderá todos os stashes.

O conserto

Execute estes comandos a partir do diretório pai acima do repository (substitua ‘foo’ pelo nome da sua pasta de projeto):

  1. Crie um backup do diretório corrompido:
    cp -R foo foo-backup
  2. Faça um novo clone do repository remoto para um novo diretório:
    git clone git@www.mydomain.de:foo foo-newclone
  3. Exclua o subdiretório .git corrompido:
    rm -rf foo/.git
  4. Mova o subdiretório .git recém-clonado para foo:
    mv foo-newclone/.git foo
  5. Exclua o restante do novo clone temporário:
    rm -rf foo-newclone

No Windows, você precisará usar:

  • copy vez de cp -R
  • rmdir /S vez de rm -rf
  • move vez de mv

Agora foo tem seu subdiretório .git original de volta, mas todas as mudanças locais ainda estão lá. git status , commit , pull , push , etc. trabalhe novamente como deveria.

Sua melhor aposta é provavelmente simplesmente voltar a clonar a partir do repository remoto (ou seja, Github ou outro). Infelizmente, você perderá todos os commits não compactados e stashed changes, no entanto, sua cópia de trabalho deverá permanecer intacta.

Primeiro faça uma cópia de backup dos seus arquivos locais. Então faça isso a partir da raiz da sua tree de trabalho:

 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 

Em seguida, confirme os arquivos alterados conforme necessário.

Trabalhando em uma VM, no meu notebook, bateria morreu, peguei esse erro;

erro: arquivo de object .git / objects / ce / theRef está vazio error: arquivo de object .git / objects / ce / theRef está vazio fatal: object solto theRef (armazenado em .git / objects / ce / theRef) está corrompido

Consegui fazer com que o repository funcionasse novamente com apenas 2 comandos e sem perder meu trabalho (arquivos modificados / alterações não confirmadas)

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

Depois que eu corri um git status , o repo estava bem e havia minhas alterações (esperando para ser cometido, faça isso agora ..).

git versão 1.9.1

Lembre-se de fazer backup de todas as alterações que você lembra, apenas no caso desta solução não funcionar e uma abordagem mais radical é necessária.

Meu computador travou enquanto eu estava escrevendo uma mensagem de commit. Após a reboot, a tree de trabalho estava como eu a deixei e fui capaz de confirmar com sucesso minhas alterações.

No entanto, quando eu tentei executar o git status eu tenho

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

Ao contrário da maioria das outras respostas, eu não estava tentando recuperar nenhum dado . Eu só precisava que o Git parasse de reclamar sobre o arquivo de object vazio.

Visão geral

O “arquivo de object” é a representação hash do git de um arquivo real com o qual você se importa. O Git acha que deveria ter uma versão com hash de some/file.whatever armazenado em .git/object/xx/12345 , e consertar o erro acabou sendo principalmente uma questão de descobrir qual arquivo o “object solto” deveria representar .

Detalhes

Possíveis opções pareciam ser

  1. Excluir o arquivo vazio
  2. Coloque o arquivo em um estado aceitável para o Git

Abordagem 1: remova o arquivo de object

A primeira coisa que tentei foi apenas mover o arquivo de object

 mv .git/objects/xx/12345 .. 

Isso não funcionou – git começou a reclamar de um link quebrado. Para a abordagem 2.

Abordagem 2: corrija o arquivo

Linus Torvalds escreveu um ótimo artigo sobre como recuperar um arquivo de object que resolveu o problema para mim. As principais etapas estão resumidas aqui.

 $> # 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 

Isso informa a você qual arquivo o object vazio deve ser um hash de. Agora você pode consertá-lo.

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

Depois de fazer isso eu verifiquei .git/objects/xx/12345 , ele não estava mais vazio, e git parou de reclamar.

Experimentar

 git stash 

Isso funcionou para mim. Ele guarda tudo o que você não cometeu e que contornou o problema.

Eu apenas experimentei isso – minha máquina caiu enquanto escrevia para o repository do Git, e ele ficou corrompido. Eu consertei da seguinte forma.

Comecei olhando quantos commits eu não tinha enviado para o repository remoto, assim:

 gitk & 

Se você não usa esta ferramenta, é muito útil – disponível em todos os sistemas operacionais, tanto quanto eu sei. Isso indicou que meu controle remoto estava perdendo dois commits. Eu, portanto, cliquei no label indicando o último commit remoto (geralmente isso será /remotes/origin/master ) para obter o hash (o hash tem 40 caracteres, mas por brevidade eu estou usando 10 aqui – isso geralmente funciona de qualquer maneira).

Aqui está:

14c0fcc9b3

Eu então clico no seguinte commit (ou seja, o primeiro que o remote não tem) e recebo o hash lá:

04d44c3298

Eu então uso os dois para fazer um patch para este commit:

 git diff 14c0fcc9b3 04d44c3298 > 1.patch 

Eu fiz o mesmo com o outro commit ausente, ie usei o hash do commit antes e o hash do commit em si:

 git diff 04d44c3298 fc1d4b0df7 > 2.patch 

Em seguida, mudei para um novo diretório, clonei o repository do controle remoto:

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

Em seguida, movi os arquivos de patch para a nova pasta e os apliquei e confirmei com suas mensagens de confirmação exatas (elas podem ser coladas no git log do git log ou na janela do gitk ):

 patch -p1 < 1.patch git commit patch -p1 < 2.patch git commit 

Isso restaurou as coisas para mim (e note que provavelmente há uma maneira mais rápida de fazer isso para um grande número de commits). No entanto, eu estava ansioso para ver se a tree no repository corrompido pode ser reparada, e a resposta é que pode. Com um repository reparado disponível como acima, execute este comando na pasta quebrada:

 git fsck 

Você terá algo assim:

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

Para fazer o reparo, eu faria isso na pasta quebrada:

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

ou seja, remova o arquivo corrompido e substitua-o por um bom. Você pode ter que fazer isso várias vezes. Finalmente, haverá um ponto em que você poderá executar o fsck sem erros. Você provavelmente terá as linhas "dangling commit" e "dangling blob" no relatório, estas são uma conseqüência de suas redefinições e alterações nesta pasta e estão OK. O coletor de lixo irá removê-los no devido tempo.

Assim (pelo menos no meu caso) uma tree corrompida não significa que os commits unpushed sejam perdidos.

Em resposta de @ user1055643 faltando a última etapa:

 $ 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 

Eu estava recebendo um erro de object solto corrupto também.

 ./objects/x/x 

Eu consertei com sucesso, indo para o diretório do object corrompido. Eu vi que os usuários atribuídos a esse object não eram os usuários do meu git. Eu não sei como isso aconteceu, mas eu corri um chown git:git naquele arquivo e depois funcionou novamente.

Esta pode ser uma solução potencial para os problemas de algumas pessoas, mas não é necessária em todas elas.

Uma garbage collection corrigiu meu problema:

 git gc --aggressive --prune=now 

Demora um tempo para concluir, mas todo object solto e / ou índice corrompido foi corrigido.

Eu recebi este erro após a minha máquina (windows) decidiu reiniciar-se. Felizmente meu repo remoto estava atualizado, então eu acabei de fazer um novo clone git ..

Eu segui muitos dos outros passos aqui; A descrição de Linus de como olhar para a tree / objects do git e descobrir o que está faltando foi especialmente útil. git-git recupera o blob corrompido

Mas no final, para mim, eu tinha objects de tree soltos / corrompidos causados ​​por uma falha parcial no disco, e os objects de tree não são recuperados com facilidade / não são cobertos por esse documento.

No final, movi os objects// conflitantes objects// para fora do caminho e usei git unpack-objects com um arquivo de pacote de um clone razoavelmente atualizado. Conseguiu restaurar os objects de tree perdidos.

Ainda me deixou com um monte de bolhas penduradas, o que pode ser um efeito colateral de descompactar coisas previamente arquivadas, e abordado em outras questões aqui

Runnning git stash; git stash pop git stash; git stash pop corrigiu meu problema

Para mim isso aconteceu devido a uma falha de energia ao fazer um git push .

As mensagens pareciam assim:

 $ 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 

Eu tentei coisas como o git fsck mas isso não ajudou. Como o travamento aconteceu durante um git push , obviamente aconteceu durante a reescrita no lado do cliente, o que acontece depois que o servidor é atualizado. Eu olhei em volta e percebi que c2388 no meu caso era um object de commit, porque era referido por inputs em .git/refs . Então eu sabia que seria capaz de encontrar c2388 quando eu olhasse para o histórico (através de uma interface web ou segundo clone).

No segundo clone, fiz um git log -n 2 c2388 para identificar o predecessor de c2388 . Então modifiquei manualmente .git/refs/heads/master e .git/refs/remotes/origin/master para ser o predecessor de c2388 vez de c2388 . Então eu poderia fazer um git fetch . A git fetch falhou algumas vezes por conflitos em objects vazios. Eu removi cada um desses objects vazios até que a git fetch bem-sucedida. Isso curou o repository.

Eu resolvi assim: Eu decidi simplesmente copiar o arquivo de object não corrompido do clone do backup para o meu repository original. Isso funcionou tão bem. (By the way: Se você não pode encontrar o object em .git / objects / pelo seu nome, provavelmente foi [embalado] [pack] para economizar espaço.)

Eu tive esse mesmo problema no meu reit git remoto nua. Depois de muita resolução de problemas, eu descobri que um dos meus colegas tinha cometido um commit no qual alguns arquivos em .git / objects tinham permissions de 440 (r – r —–) ao invés de 444 (r – r – r -). Depois de pedir ao colega de trabalho que alterasse as permissions com “chmod 444 -R objects” dentro do repository nulo do git, o problema foi corrigido.

Nós apenas tivemos o caso aqui. Aconteceu que o problema era a propriedade do arquivo corrompido era root em vez do nosso usuário normal. Isso foi causado por um commit feito no servidor após alguém ter feito um “sudo su -“.

Primeiro, identifique seu arquivo corrompido com:

 $> git fsck --full 

Você deve receber uma resposta como esta:

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

Vá na pasta onde está o arquivo corrompido e faça um:

 $> ls -la 

Verifique a propriedade do arquivo corrompido. Se isso é diferente, basta voltar à raiz do seu repo e fazer um:

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

Espero que ajude!

Eu só tive um problema como esse. Meu problema específico foi causado por uma falha no sistema que corrompeu a confirmação mais recente (e, portanto, também a ramificação principal). Eu não tinha empurrado e queria refazer esse commit. No meu caso particular, eu pude lidar com isso assim:

  1. Faça um backup de .git/ : rsync -a .git/ git-bak/
  2. Verifique .git/logs/HEAD e encontre a última linha com um ID de confirmação válido. Para mim, esse foi o segundo commit mais recente. Isso foi bom, porque eu ainda tinha as versões de diretório de trabalho do arquivo e, portanto, a versão que eu queria.
  3. Faça um branch nesse commit: git branch temp
  4. refazer o commit quebrado com os arquivos no diretório de trabalho.
  5. git reset master temp para mover o branch master para o novo commit que você fez no passo 2.
  6. git checkout master e verifique se está correto com o git log .
  7. git branch -d temp .
  8. git fsck --full , e agora deve ser seguro excluir quaisquer objects corrompidos que o fsck encontre.
  9. Se tudo parece bom, tente empurrar. Se isso funciona,

Isso funcionou para mim. Eu suspeito que este é um cenário razoavelmente comum, já que o commit mais recente é o mais provável de ser corrompido, mas se você perder mais um, você provavelmente ainda pode usar um método como este, com o uso cuidadoso do git cherrypick , e o reflog em .git .git/logs/HEAD .

Quando eu tive esse problema eu fiz backup de minhas alterações recentes (como eu sabia o que tinha mudado), em seguida, apaguei o arquivo que estava reclamando em .git / location. Então eu fiz um puxão. Tome cuidado, isso pode não funcionar para você.

Basta remover a pasta .git e adicioná-lo novamente. Essa solução simples funcionou para mim.