Git:"objecto solto corrompido"
$ git gc
error: Could not read 3813783126d41a3200b35b6681357c213352ab31
fatal: bad tree object 3813783126d41a3200b35b6681357c213352ab31
error: failed to run repack
Alguém sabe o que fazer?
A partir de cat-file recebo isto:
$ git cat-file -t 3813783126d41a3200b35b6681357c213352ab31
error: unable to find 3813783126d41a3200b35b6681357c213352ab31
fatal: git cat-file 3813783126d41a3200b35b6681357c213352ab31: bad file
e do git fsck eu recebo isto (não sei se está 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 me pode ajudar a decifrar isto?
20 answers
Você poderia realmente reconstruí-lo se você não consegue encontrar uma versão válida de outra pessoa, adivinhando quais arquivos devem estar lá. Poderá querer ver se as datas e horas dos objectos correspondem a ele. Podem ser as bolhas relacionadas. Você pode inferir a estrutura do objeto da árvore desses objetos.
Olha para isto. Os Screencasts Git de Scott Chacon sobre os git internals. Isto vai mostrar como o git trabalha sob o capô e como fazer esse trabalho de detetive se você está realmente preso e não pode obter esse objeto de outra pessoa.Tive o mesmo problema (não sei porquê).
Esta correção requer o acesso a uma cópia remota do repositório sem restrições, e irá manter a sua cópia de trabalho local intacta.
Mas tem algumas desvantagens:- Você perderá o registro de quaisquer commits que não tenham sido pressionados, e terá que reiniciá-los.
Vais perder todos os esconderijos.
A dose
Execute estes comandos a partir da pasta-mãe por cima do seu repo (substitua 'foo' pelo nome da sua pasta do projecto):
- crie uma cópia de segurança da pasta corrupta:
cp -R foo foo-backup
- faça um novo clone do repositório remoto para uma nova pasta:
git clone [email protected]:foo foo-newclone
Apague os corruptos .subdirectório git: - apaga o resto do novo clone temporário:
rm -rf foo-newclone
rm -rf foo/.git
Mova o recém clonado .subdirectório git em foo:mv foo-newclone/.git foo
Nas janelas terá de Uso:
-
copy
em vez decp -R
-
rmdir /S
em vez derm -rf
-
move
em vez demv
Agora foo tem a sua subdiretoria original .git
de volta, mas todas as mudanças locais ainda estão lá. git status
, commit
, pull
, push
, etc. voltem a trabalhar como deviam.
Sua melhor aposta é provavelmente para simplesmente clonar a partir do Remote repo (ie. Github ou outro). Infelizmente, você perderá qualquer commits e alterações escondidas, no entanto a sua cópia de trabalho deve permanecer intacta.
Primeiro faça uma cópia de segurança dos seus ficheiros locais. Então faça isto pela raiz da sua árvore 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, enviar todos os arquivos alterados conforme necessário.
Erro: ficheiro do objecto .o git/objects/ce/theRef está vazio: object arquivo .git / objects / ce / theRef is empty fatal: loose object theRef (armazenar .git / objects/ce / theRef) é corrupto
Consegui que o repo funcionasse novamente com apenas 2 comandos e sem perder o meu trabalho (ficheiros modificados/alterações por persistir)
find .git/objects/ -size 0 -exec rm -f {} \;
git fetch origin
Depois disso, fiz um acordo. houve as minhas mudanças (à espera de ser internado, faça-o agora..).
Git version 1.9.1
Lembre-se de fazer backup de todas as mudanças que se lembre, só no caso desta solução não funcionar e uma abordagem mais radical é necessária.
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. Só precisava que o Git parasse de se queixar do ficheiro do objecto vazio.
Panorâmica
O "ficheiro objecto" é a representação tracejada do git de um ficheiro real que te interessa. O Git acha que deve ter uma versão hashed de some/file.whatever
armazenada em .git/object/xx/12345
, e corrigir o erro acabou por ser principalmente uma questão de descobrir qual arquivo o "objeto solto" era suposto representar.
Detalhes
As opções possíveis pareciam ser
- apaga o ficheiro vazio
- coloca o ficheiro num estado aceitável para o Git
Aproximação 1: remover o ficheiro do objecto
A primeira coisa que tentei foi mover o objecto. ficheiromv .git/objects/xx/12345 ..
Isso não funcionou. o git começou a queixar-se de uma ligação quebrada. Aproximação 2.
Aproximação 2: corrigir o ficheiro
Linus Torvalds tem um grande writeup de Como recuperar um arquivo objeto que resolveu o problema para mim. Passos-chave são resumidos 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
Isto diz - lhe de que ficheiro o objecto vazio é suposto ser um hash of. Agora podes repará-lo.
$> git hash-object -w path/to/your_file.whatever
Depois de fazer isso eu verifiquei .git/objects/xx/12345
, ele já não estava vazio, e git deixou de se queixar.
Tenta
git stash
Isto funcionou comigo. Esconde qualquer coisa que não tenhas cometido e que tenha contornado o problema.
Comecei a ver quantos commits eu não tinha empurrado para o remoto repo, assim:
gitk &
Se não usar esta ferramenta, está muito disponível em todos os sistemas operacionais, tanto quanto sei. Isto indicava que faltavam dois commits ao meu comando. Eu, portanto, clicei no rótulo que indica o mais recente commit remoto (normalmente este será /remotes/origin/master
) para obter o hash(o hash é de 40 caracteres, mas para brevidade eu estou usando 10 aqui-isso geralmente funciona de qualquer maneira).
14c0fcc9b3
Em seguida, clique no seguinte commit (ou seja, o primeiro que o remoto não tem) e obter o hash lá:
04d44c3298
Então uso ambos para fazer um patch para este commit:
git diff 14c0fcc9b3 04d44c3298 > 1.patch
Então fiz o mesmo com o outro commit em falta., ou seja, eu usei o hash do commit antes e o hash do próprio commit:
git diff 04d44c3298 fc1d4b0df7 > 2.patch
Depois mudei-me para um novo directório, clonei o repo do remoto:
git clone [email protected]:username/repo.git
Depois movi os ficheiros patch para a nova pasta, aplicei-os e comprometi-os com as suas mensagens exactas de commit (estas podem ser coladas a partir de git log
ou da janela 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 fazê-lo para um grande número de commits). No Entanto, Estava ansioso para ver se a árvore no repo corrompido pode ser reparado, e a resposta é que pode. Com um repo reparado disponível como em cima, execute este comando na pasta quebrada:
git fsck
Vais ter algo assim:
error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
Para fazer a reparação, eu faria isso na pasta quebrada:
rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
Isto é, remova o ficheiro corrompido e substitua-o por um bom. Você pode ter que fazer isso várias vezes. Finalmente, haverá um ponto onde você pode executar fsck
sem erros. Você provavelmente terá" dangling commit "e" dangling blob " linhas no relatório, estas são uma consequência de seus rebases e emendas nesta pasta, e são OK. O coletor de lixo irá removê-los na devida altura.
Assim (pelo menos no meu caso) uma árvore corrompida não significa que os commits não esmagados sejam perdidos.
Em resposta a @user1055643 faltando o último passo:
$ 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
./objects/x/x
Corrigi-o com sucesso ao entrar no directório do objecto corrupto. Eu vi que os usuários atribuídos a esse objeto era não do meu usuário git. eu não sei como isso aconteceu, mas eu corri um chown git:git
Naquele arquivo e então ele funcionou novamente.
A recolha do lixo resolveu o meu problema:
git gc --aggressive --prune=now
Demora algum tempo a completar, mas cada objecto solto e / ou índice corrompido foi corrigido.
Eu segui muitos dos outros passos aqui; a descrição de Linus de como olhar para a árvore/objetos git e descobrir o que está faltando foi especialmente útil. git-git recupera blob corrompido
Mas no final, para mim, eu tinha objetos de árvore frouxos/corruptos causados por uma falha parcial do disco, e objetos de árvore não são tão facilmente recuperados/não cobertos por esse doc.
No final, eu movi o conflito {[[0]} para fora do caminho, e usei {[[1]} com um arquivo de pacote de um razoavelmente até clone de data. Foi capaz de restaurar os objetos da árvore em falta.
Ainda me deixou com um monte de bolhas balançando, o que pode ser um efeito colateral de desempacotar coisas previamente arquivadas, e endereçado em outras perguntas Aqui
Runnning git stash; git stash pop
resolveu o meu problema
$ 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
Tentei coisas como ... mas isso não ajudou.
Uma vez que o estoiro aconteceu durante um git push
, obviamente aconteceu durante a reescrita do lado cliente, o que acontece depois do servidor ser atualizado. Eu olhei em volta e percebi que c2388
no meu caso era um objeto de commit, porque ele era referido por entradas em .git/refs
. Então eu sabia que eu seria capaz de encontrar c2388
Quando Eu olho 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 eu modifiquei manualmente .git/refs/heads/master
e .git/refs/remotes/origin/master
para ser o antecessor de c2388
em vez de c2388
.
Então eu poderia fazer um git fetch
.
O git fetch
falhou algumas vezes por conflitos em objectos vazios. Removi cada um destes objectos vazios até que git fetch
tenha sucesso. Isso curou o repositório.
$> git fsck --full
Deve receber uma resposta como esta:
fatal: loose object 11b25a9d10b4144711bf616590e171a76a35c1f9 (stored in .git/objects/11/b25a9d10b4144711bf616590e171a76a35c1f9) is corrupt
Vai para a pasta onde está o ficheiro corrompido e faz um:
$> ls -la
Verifique a propriedade do ficheiro corrupto. Se isso for diferente, apenas ... volte para a raiz do seu repo e faça um:
$> sudo chown -R YOURCORRECTUSER:www-data .git/
Espero que ajude!
- faz uma cópia de segurança de
.git/
:rsync -a .git/ git-bak/
- Verifique
.git/logs/HEAD
, e encontre a última linha com um ID de persistência válido. Para mim, este foi o segundo compromisso mais recente. Isto foi bom, porque eu ainda tinha o versões de diretório de trabalho do arquivo, e assim todas as versões que eu queria. - faça um branch nesse commit:
git branch temp <commit-id>
- faça de novo o commit quebrado com os ficheiros no directório de trabalho.
-
git reset master temp
para mover o ramo mestre para o novo commit que você fez no Passo 2. -
git checkout master
e verifique se parece bem comgit log
. -
git branch -d temp
. -
git fsck --full
, e agora deve ser seguro apagar quaisquer objectos corrompidos que o fsck encontre.
Se tudo parecer bem, tenta. empilhar. Se isso funcionar,
git cherrypick
, e o reflog em .git/logs/HEAD
.
Quando eu tinha este problema eu fiz backup de minhas mudanças recentes (como eu sabia o que eu tinha mudado), em seguida, apagou aquele arquivo que estava reclamando em .git / localização. Depois fiz uma tentativa. Tem cuidado, isto pode não resultar para ti.