Inizialmente prova i seguenti comandi (riesegui di nuovo se necessario):
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
E poi hai ancora i problemi, prova puoi:
rimuovere tutti gli oggetti corrotti, ad es
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt
$ rm -v .git/objects/06/91c5...51e5
rimuovere tutti gli oggetti vuoti, es
error: object file .git/objects/06/91c5...51e5 is empty
$ find .git/objects/ -size 0 -exec rm -vf "{}" \;
controlla un messaggio di "collegamento interrotto" di:
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
Questo ti dirà da quale file proviene il blob corrotto!
per recuperare il file, potresti essere davvero fortunato e potrebbe essere la versione che hai già estratto nel tuo albero di lavoro:
git hash-object -w my-magic-file
di nuovo, e se emette l'SHA1 mancante (4b945 ..) ora hai finito!
supponendo che fosse una versione precedente che era rotta, il modo più semplice per farlo è farlo:
git log --raw --all --full-history -- subdirectory/my-magic-file
e questo ti mostrerà l'intero registro per quel file (tieni presente che l'albero che avevi potrebbe non essere l'albero di primo livello, quindi devi capire in quale sottodirectory si trovava da solo), quindi ora puoi ricreare il oggetto mancante con hash-object di nuovo.
per ottenere un elenco di tutti i ref con commit, alberi o blob mancanti:
$ git for-each-ref --format='%(refname)' | while read ref; do git rev-list --objects $ref >/dev/null || echo "in $ref"; done
Potrebbe non essere possibile rimuovere alcuni di questi ref usando i normali comandi branch -d o tag -d, poiché moriranno se git noterà il danneggiamento. Quindi usa il comando idraulico git update-ref -d $ ref invece. Nota che in caso di rami locali, questo comando potrebbe lasciare la configurazione del ramo obsoleto in .git / config. Può essere cancellato manualmente (cerca la sezione [branch "$ ref"]).
Dopo che tutti gli arbitri sono puliti, potrebbero esserci ancora commit non funzionanti nel reflog. Puoi cancellare tutti i reflog usando git reflog expire --expire = now --all. Se non vuoi perdere tutti i tuoi reflog, puoi cercare i singoli ref per reflog non funzionanti:
$ (echo HEAD; git for-each-ref --format='%(refname)') | while read ref; do git rev-list -g --objects $ref >/dev/null || echo "in $ref"; done
(Notare l'aggiunta dell'opzione -g a git rev-list.) Quindi, utilizzare git reflog expire --expire = now $ ref su ciascuno di essi. Quando tutti i ref e reflog non funzionanti sono stati eliminati, eseguire git fsck --full per verificare che il repository sia pulito. Gli oggetti penzolanti vanno bene.
Di seguito puoi trovare un utilizzo avanzato dei comandi che potenzialmente possono causare la perdita dei tuoi dati nel tuo repository git se non usati saggiamente, quindi fai un backup prima di danneggiare accidentalmente ulteriormente il tuo git. Prova a tuo rischio se sai cosa stai facendo.
Per spostare il ramo corrente sopra il ramo a monte dopo il recupero:
$ git pull --rebase
Puoi anche provare a controllare il nuovo ramo ed eliminare quello vecchio:
$ git checkout -b new_master origin/master
Per trovare l'oggetto danneggiato in git per la rimozione, prova il seguente comando:
while [ true ]; do f=`git fsck --full 2>&1|awk '{print $3}'|sed -r 's/(^..)(.*)/objects\/\1\/\2/'`; if [ ! -f "$f" ]; then break; fi; echo delete $f; rm -f "$f"; done
Per OSX, usa sed -E
invece di sed -r
.
Un'altra idea è decomprimere tutti gli oggetti dai file pack per rigenerare tutti gli oggetti all'interno di .git / objects, quindi prova a eseguire i seguenti comandi all'interno del tuo repository:
$ cp -fr .git/objects/pack .git/objects/pack.bak
$ for i in .git/objects/pack.bak/*.pack; do git unpack-objects -r < $i; done
$ rm -frv .git/objects/pack.bak
Se sopra non aiuta, puoi provare a rsync o copiare gli oggetti git da un altro repository, ad es
$ rsync -varu git_server:/path/to/git/.git local_git_repo/
$ rsync -varu /local/path/to/other-working/git/.git local_git_repo/
$ cp -frv ../other_repo/.git/objects .git/objects
Per riparare il ramo rotto durante il tentativo di checkout come segue:
$ git checkout -f master
fatal: unable to read tree 5ace24d474a9535ddd5e6a6c6a1ef480aecf2625
Prova a rimuoverlo ed eseguire nuovamente il checkout dall'upstream:
$ git branch -D master
$ git checkout -b master github/master
Nel caso in cui git ti porti in uno stato disconnesso, controlla master
e unisci in esso il ramo disconnesso.
Un'altra idea è rebase il master esistente in modo ricorsivo:
$ git reset HEAD --hard
$ git rebase -s recursive -X theirs origin/master
Guarda anche:
.git
cartella ovviamente) nel repository appena clonato ... e poi fattogit status
nel nuovo repository ... git rileva correttamente tutte le modifiche interessate ai miei file e posso ricominciare il mio lavoro.