2013-01-01 16 views
7

Ho una situazione con un oggetto corrotto in un repository.Rimuovi git blob corrotto dal repository

$ git push 
... 
fatal: loose object 95b6a826cadae849f4932a71d6735ab6ceb47cab (stored in .git/objects/95/b6a826cadae849f4932a71d6735ab6ceb47cab) is corrupt 
... 

E so che questo objet è un blob collegato a da un vecchio commit:

$ git fsck --full 
Checking object directories: 100% (256/256), done. 
broken link from tree 27e8e7d5b94c1dad5410a8204089828a167a0eaf 
      to blob 95b6a826cadae849f4932a71d6735ab6ceb47cab 

ho fatto il classic steps to recover the blob from the FAQ ma sembra non c'è altra copia di esso da nessuna parte che posso trovare (Sto lavorando da solo e non ho spinto al telecomando per un po 'quindi non c'è) quindi non posso recuperarlo.

Questo blob è in realtà la prima versione di un file che è stato modificato molto da allora. Sto bene perdendo le informazioni su quella versione del file. Quindi vorrei solo rimuoverlo dal commit che sta puntando ad esso. Come lo posso fare?

+0

Prova a guardare alcune delle soluzioni qui: http://stackoverflow.com/q/4254389/1031900 –

+0

Questa domanda riguarda un albero danneggiato, che è un po 'diverso. Nessuna di queste risposte può aiutarmi, purtroppo. Ho intenzione di provare alcune cose e lo posterò qui se funzionano. –

risposta

4

OK, alla fine ho capito.

Versione breve: ho modificato il commit puntando al blob corrotto per rimuoverlo dalla cronologia.

Versione lunga: ho pensato che dal momento che sapevo cosa fosse il file e volevo solo farlo sparire dal commit, allora potevo semplicemente modificare il vecchio commit. Non mi aspettavo davvero che funzionasse, ma alla fine lo ha fatto.

Devo precisare che ho rimosso il blob in .git/objects nel provare cose precedenti, ed è probabilmente importante il perché ha funzionato.

In primo luogo, ho dovuto sapere che cosa è stato commettere. Per questo ho usato il comando

git log --raw --all --full-history -- subdir/my-file 

ho trovato il commit è stato chiamato 966a46 ....

poi ho fatto i passi per modificarlo. Dal momento che era un vecchio commit, ho usato

git rebase -- interactive 966a46^ 

Il mio editore è entrato con una riga per ogni commit, e ho cambiato "pick" a "modifica" di fronte al commesso ho voluto modificare.

Il comando git status mi ha mostrato che il file ho voluto cancellare è stata modificata:

# Changes not staged for commit: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
#  modified: subdir/my-file 

ho voluto rimuoverlo dal commettere, così ho fatto rm subdir/my-file. git status poi mi ha mostrato:

#  deleted: subdir/my-file 

Questo sembrava promettente. Così ho semplicemente commesso l'modificato commettere e ha continuato il rebase:

git commit --all --amend 
git rebase --continue 

Ma dopo aver ricalcolato pochi commette è venuto a mancare con questo errore:

error: could not apply 45c2315... did some fancy things 
fatal: unable to read 95b6a826cadae849f4932a71d6735ab6ceb47cab 

45c2315 è stato il primo commit in cui la mia file è stato modificato dopo essere stato creato. Dal momento che non ha trovato la versione precedente del file, ha appena fallito.

git status mi ha mostrato, tra le altre cose:

# Unmerged paths: 
# (use "git reset HEAD <file>..." to unstage) 
# (use "git add/rm <file>..." as appropriate to mark resolution) 
# 
#  deleted by us:  subdir/my-file 

io non sono realmente sicuro che cosa significa, ma questo commit doveva essere il primo in cui sembrerebbe il file, dopo la correzione. Quindi non volevo che fosse cancellato, ma al contrario, aggiunto al commit! Così ho fatto

git add subdir/my-file 

E sicuramente git status mostrato come un "nuovo file".

Poi ho fatto git rebase --continue e tutto è andato bene, e il rebase è stato un successo.

git push è andato poi in modo regolare invece di fallire sul blob rotto.

Ma c'erano ancora un problema, perché git fsck era ancora in mancanza:

$ git fsck --full 
Checking object directories: 100% (256/256), done. 
broken link from tree 27e8e7d5b94c1dad5410a8204089828a167a0eaf 
       to blob 95b6a826cadae849f4932a71d6735ab6ceb47cab 

E git gc fallito anche, quando gli ho chiesto di potare tutto. Quindi ho capito che la migliore linea d'azione era, dal momento che avevo spinto con successo, per clonare tutto in un nuovo repository e lavorare da lì.

Problemi correlati