Git: “Oggetto libero corrotto”

Ogni volta che tiro dal mio telecomando, ottengo il seguente errore sulla compressione. Quando eseguo la compressione manuale, ottengo lo stesso:

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

Qualcuno sa, cosa fare a tale proposito?

Da cat-file ho capito:

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

E da git fsck ottengo questo (non so se è effettivamente correlato):

 $ 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 

Qualcuno può aiutarmi a decifrarlo?

Sembra che tu abbia un object ad albero corrotto. Avrai bisogno di ottenere quell’object da qualcun altro. Speriamo che abbiano una versione incorrotta.

Potresti effettivamente ricostruirlo se non riesci a trovare una versione valida da qualcun altro indovinando quali file dovrebbero esserci. Potresti voler vedere se le date e le ore degli oggetti corrispondono ad esso. Quelli potrebbero essere i blob correlati. È ansible dedurre la struttura dell’object albero da tali oggetti.

Date un’occhiata a Screencast Git di Scott Chacon per quanto riguarda git internals. Questo ti mostrerà come funziona git sotto il cofano e come fare questo lavoro investigativo se sei davvero bloccato e non riesci a ottenere quell’object da qualcun altro.

Ho avuto lo stesso problema (non so perché).

Questa correzione richiede l’accesso a una copia remota incorrotta del repository e manterrà intatta la tua copia di lavoro locale.

Ma ha alcuni inconvenienti:

  • Perderai la registrazione di qualsiasi commit che non è stato spinto e dovrai ricominciarli.
  • Perderete qualsiasi scorta.

La correzione

Esegui questi comandi dalla directory padre sopra il repository (sostituisci ‘foo’ con il nome della cartella del tuo progetto):

  1. Creare un backup della directory danneggiata:
    cp -R foo foo-backup
  2. Crea un nuovo clone del repository remoto in una nuova directory:
    git clone git@www.mydomain.de:foo foo-newclone
  3. Elimina la sottodirectory .git corrotta:
    rm -rf foo/.git
  4. Sposta la sottodirectory .git appena clonata in foo:
    mv foo-newclone/.git foo
  5. Elimina il resto del nuovo clone temporaneo:
    rm -rf foo-newclone

Su Windows è necessario utilizzare:

  • copy invece di cp -R
  • rmdir /S invece di rm -rf
  • move invece di mv

Ora foo ha la sua sottodirectory originale .git , ma tutte le modifiche locali sono ancora lì. git status , commit , pull , push , ecc. funzionano di nuovo come dovrebbero.

La soluzione migliore è probabilmente quella di ricodificare semplicemente dal repository remoto (ad esempio Github o altro). Sfortunatamente perderete qualsiasi commit impunito e modifiche nascoste, tuttavia la vostra copia di lavoro dovrebbe rimanere intatta.

Prima crea una copia di backup dei tuoi file locali. Quindi fai questo dalla radice del tuo albero di lavoro:

 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 

Quindi, commetti tutti i file modificati secondo necessità.

Lavorando su una VM, nel mio notebook, la batteria è morta, ho ricevuto questo errore;

errore: file object .git / objects / ce / theRef è vuoto errore: file object .git / objects / ce / theRef è vuoto fatale: object loose theRef (memorizzato in .git / objects / ce / theRef) è corrotto

Sono riuscito a far funzionare nuovamente il repository con soli 2 comandi e senza perdere il lavoro (file modificati / modifiche non salvate)

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

Dopo di che ho eseguito uno git status , il repository è andato bene e c’erano i miei cambiamenti (in attesa di essere commesso, fallo ora ..).

git versione 1.9.1

Ricordati di fare il backup di tutte le modifiche che ricordi, nel caso in cui questa soluzione non funzioni e sia necessario un approccio più radicale.

Il mio computer si è bloccato durante la scrittura di un messaggio di commit. Dopo il riavvio, l’albero di lavoro era come l’avevo lasciato e sono riuscito a confermare le modifiche.

Tuttavia, quando ho provato a eseguire lo git status ho ottenuto

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

A differenza della maggior parte delle altre risposte, non stavo cercando di recuperare alcun dato . Avevo solo bisogno che Git smettesse di lamentarsi del file object vuoto.

Panoramica

Il “file object” è la rappresentazione con hash di git di un file reale che ti interessa. Git pensa che dovrebbe avere una versione hash di some/file.whatever memorizzata in .git/object/xx/12345 , e la correzione dell’errore si è rivelata principalmente una questione di capire quale file avrebbe dovuto rappresentare “l’object libero” .

Dettagli

Le opzioni possibili sembravano essere

  1. Elimina il file vuoto
  2. Ottieni il file in uno stato accettabile per Git

Metodo 1: rimuovi il file object

La prima cosa che ho provato è stata spostare il file object

 mv .git/objects/xx/12345 .. 

Questo non ha funzionato: Git ha iniziato a lamentarsi di un collegamento interrotto. Verso l’avvicinamento 2.

Approccio 2: correggi il file

Linus Torvalds ha una grande descrizione di come recuperare un file object che ha risolto il problema per me. I passaggi chiave sono riassunti qui.

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

Questo ti dice quale file l’object vuoto dovrebbe essere un hash di. Ora puoi ripararlo.

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

Dopo averlo fatto ho controllato .git/objects/xx/12345 , non era più vuoto e git ha smesso di lamentarsi.

Provare

 git stash 

Questo ha funzionato per me. Mette in ordine tutto ciò che non hai commesso e questo ha aggirato il problema.

L’ho appena sperimentato: la mia macchina si è bloccata durante la scrittura sul repository Git e si è danneggiata. L’ho risolto come segue.

Ho iniziato osservando quanti commit non avevo spinto al repository remoto, quindi:

 gitk & 

Se non si utilizza questo strumento è molto utile – disponibile su tutti i sistemi operativi, per quanto ne so. Ciò indicava che il mio telecomando mancava due commit. Ho quindi cliccato sull’etichetta che indica l’ultimo commit remoto (solitamente questo sarà /remotes/origin/master ) per ottenere l’hash (l’hash è lungo 40 caratteri, ma per brevità sto usando 10 qui – questo di solito funziona comunque).

Ecco qui:

14c0fcc9b3

Quindi faccio clic sul seguente commit (ovvero il primo che il telecomando non ha) e ottengo l’hash lì:

04d44c3298

Quindi uso entrambi di questi per creare una patch per questo commit:

 git diff 14c0fcc9b3 04d44c3298 > 1.patch 

Ho fatto lo stesso con l’altro commit mancante, cioè ho usato l’hash del commit prima e l’hash del commit stesso:

 git diff 04d44c3298 fc1d4b0df7 > 2.patch 

Poi sono passato a una nuova directory, clonato il repository dal telecomando:

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

Ho quindi spostato i file di correzione nella nuova cartella, li ho applicati e li ho impegnati con i loro messaggi di commit esatti (che possono essere incollati da git log o dalla finestra di gitk ):

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

Questo mi ha restituito le cose (e noto che probabilmente c'è un modo più veloce per farlo per un gran numero di commit). Tuttavia, volevo vedere se l'albero nel repository corrotto può essere riparato, e la risposta è che può. Con un repository riparato disponibile come sopra, eseguire questo comando nella cartella interrotta:

 git fsck 

Otterrai qualcosa di simile a questo:

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

Per eseguire la riparazione, lo farei nella cartella interrotta:

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

cioè rimuovere il file danneggiato e sostituirlo con uno buono. Potrebbe essere necessario farlo più volte. Finalmente ci sarà un punto in cui è ansible eseguire fsck senza errori. Probabilmente avrai delle righe di "dangling commit" e "dangling blob" nel report, queste sono una conseguenza dei tuoi rebases e modifiche in questa cartella, e sono OK. Il garbage collector li rimuoverà a tempo debito.

Quindi (almeno nel mio caso) un albero corrotto non significa che i commit non sparati sono persi.

In risposta a @ user1055643 manca l’ultimo passaggio:

 $ 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 

Stavo ricevendo anche un errore di object loose corrotto.

 ./objects/x/x 

Ho risolto con successo andando nella directory dell’object corrotto. Ho visto che gli utenti assegnati a quell’object non erano i miei utenti git. Non so come sia successo, ma ho eseguito un chown git:git su quel file e poi ha funzionato di nuovo.

Questa potrebbe essere una potenziale soluzione per i problemi di alcune persone ma non tutte necessarie.

Una garbage collection ha risolto il mio problema:

 git gc --aggressive --prune=now 

Ci vuole un po ‘per completare, ma ogni object libero e / o indice corrotto è stato corretto.

Ho ricevuto questo errore dopo che la mia macchina (Windows) ha deciso di riavviarsi da sola. Per fortuna il mio repository remoto era aggiornato, quindi ho appena fatto un nuovo clone git ..

Ho seguito molti degli altri passaggi qui; La descrizione di Linus su come osservare l’albero / oggetti di git e trovare ciò che manca era particolarmente utile. git-git recupera il blob corrotto

Ma alla fine, per me, avevo degli oggetti albero liberi / corrotti causati da un errore parziale del disco, e gli oggetti ad albero non sono così facilmente recuperabili / non coperti da quel documento.

Alla fine, ho spostato gli objects// conflitto objects// e ho usato git unpack-objects con un file pack da un clone ragionevolmente aggiornato. È stato in grado di ripristinare gli oggetti dell’albero mancanti.

Mi hanno lasciato ancora un sacco di blob penzolanti, che possono essere un effetto collaterale del disimballaggio di materiale precedentemente archiviato e affrontati in altre domande qui

Scorta git stash; git stash pop git stash; git stash pop risolto il mio problema

Per me questo è accaduto a causa di un’interruzione di corrente mentre facevo una git push .

I messaggi sembravano così:

 $ 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 

Ho provato cose come git fsck ma questo non ha aiutato. Dal momento che l’arresto si è verificato durante una git push , ovviamente è successo durante la riscrittura sul lato client, che si verifica dopo l’aggiornamento del server. Mi sono guardato intorno e ho capito che c2388 nel mio caso era un object commit, perché era indicato da voci in .git/refs . Quindi sapevo che sarei stato in grado di trovare c2388 quando guardo la storia (attraverso un’interfaccia web o un secondo clone).

Sul secondo clone ho fatto un git log -n 2 c2388 per identificare il predecessore di c2388 . Poi ho modificato manualmente .git/refs/heads/master e .git/refs/remotes/origin/master per essere il predecessore di c2388 invece di c2388 . Quindi potrei fare un git fetch . git fetch avuto esito negativo alcune volte per conflitti su oggetti vuoti. Ho rimosso ognuno di questi oggetti vuoti fino a git fetch riuscito. Questo ha guarito il repository.

Ho risolto in questo modo: ho deciso di copiare semplicemente il file object non danneggiato dal clone del backup nel mio repository originale. Questo ha funzionato altrettanto bene. (A proposito: se non riesci a trovare l’object in .git / objects / con il suo nome, probabilmente è stato [confezionato] [pacchetto] per risparmiare spazio.)

Ho avuto questo stesso problema nel mio repository Git remoto. Dopo aver risolto molti problemi, ho scoperto che uno dei miei colleghi aveva effettuato un commit in cui alcuni file in .git / objects avevano i permessi di 440 (r – r —–) invece di 444 (r – r – r -). Dopo aver chiesto al collega di modificare i permessi con “chmod 444 -R oggetti” all’interno del repository git nudo, il problema è stato risolto.

Abbiamo appena avuto il caso qui. È successo che il problema era che la proprietà del file corrotto era root al posto del nostro normale utente. Questo è stato causato da un commit fatto sul server dopo che qualcuno ha fatto un “sudo su -“.

Innanzitutto, identifica il tuo file corrotto con:

 $> git fsck --full 

Dovresti ricevere una risposta come questa:

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

Vai nella cartella in cui si trova il file corrotto e fai un:

 $> ls -la 

Controlla la proprietà del file corrotto. Se è diverso, basta tornare alla root del repository e fare un:

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

Spero che sia d’aiuto!

Ho appena avuto un problema come questo. Il mio problema particolare è stato causato da un arresto anomalo del sistema che ha danneggiato il commit più recente (e quindi anche il ramo principale). Non avevo spinto, e volevo rifare il commit. Nel mio caso particolare, sono stato in grado di gestirlo in questo modo:

  1. Eseguire un backup di .git/ : rsync -a .git/ git-bak/
  2. Controlla .git/logs/HEAD e trova l’ultima riga con un ID commit valido. Per me, questo è stato il secondo impegno più recente. Questo era buono, perché avevo ancora le versioni di directory di lavoro del file, e quindi ogni versione volevo.
  3. Crea un ramo su quel commit: git branch temp
  4. rifare il commit interrotto con i file nella directory di lavoro.
  5. git reset master temp per spostare il ramo master sul nuovo commit effettuato nel passaggio 2.
  6. git checkout master e controlla che sia a posto con git log .
  7. git branch -d temp .
  8. git fsck --full , e ora dovrebbe essere sicuro di cancellare qualsiasi object danneggiato trovato da fsck.
  9. Se tutto sembra a posto, prova a spingere. Se funziona,

Ha funzionato per me. Sospetto che questo sia uno scenario ragionevolmente comune, dal momento che il commit più recente è il più probabile a essere corrotto, ma se ne perdi uno più indietro, puoi probabilmente usare ancora un metodo come questo, con un uso attento di git cherrypick , e il reflog in .git/logs/HEAD .

Quando ho avuto questo problema, ho eseguito il backup delle mie recenti modifiche (poiché sapevo cosa avevo cambiato), quindi ho cancellato quel file che si stava lamentando in .git / location. Poi ho fatto un tiro d’idiota. Stammi bene, potrebbe non funzionare per te.

Basta rimuovere la cartella .git e aggiungerla di nuovo. Questa semplice soluzione ha funzionato per me.