2012-06-07 1 views
7

Ho faticato con alcuni problemi di fine riga circa 20 commit indietro e alcune cose strane sono successe. Ora git spettacoli fsck:git tree contiene voci di file duplicate

Checking object directories 100% (256/256), done. 
error in tree ee2060e71cb36d33be5ddc1fe9ca8d7dd0ab35cd: contains duplicate file entries 
Checking objects: 100% (8633/8633), done. 

e git spettacolo ee2060 mostra:

File1.cs 
File2.cs 
File2.cs 
File2.cs 
File3.cs 

Questo mi impedisce di spingere per il mio telecomando. git push shows:

error: unpack failed: index-pack abnormal exit 
To https://github.com/username/Project.git 
! [remote rejected] master -> master (n/a (unpacker error)) 
error: failed to push some refs to 'https://github.com/username/Project.git' 

Ho provato il reimballaggio e la raccolta dei rifiuti. Come posso risolvere questo problema?

risposta

4

ho finalmente risolto il pronti contro termine nel modo seguente

  1. fare un clone fresca da GitHub, che comprendeva solo commit prima che il problema si è verificato
  2. aggiungere il mio incasinato repo dal filesystem come un telecomando sul nuovo clone
  3. faticosamente controllare impegna dal cattivo repo nella copia di lavoro del nuovo clone

    git checkout fe3254FIRSTCOMMITAFTERORIGIN/MASTER/HEAD . // note the dot at the end 
    // without the dot, you move your head to the commit instead of the commit 
    // to the working copy, and seems to bring the corrupt object into your good clone 
    
  4. commi t ciascuna a sua volta, copiare manualmente il messaggio di commit dall'altro repo
  5. rimuovere il repo corrotto da telecomandi
  6. spazzatura raccogliere + potare

    git gc --aggressive --prune=now 
    
  7. piangere felicemente come git fsck non mostra voci di file duplicati
+0

Perché suggerire - aggressivo? L'unica cosa che fa è ignorare tutte le precedenti informazioni delta raccolte. Maggiori informazioni: http://metalinguist.wordpress.com/2007/12/06/the-woes-of-git-gc-aggressive-and-how-git-deltas-work/ – riezebosch

+0

@riezebosch Non ricordo perché Ho incluso - aggressivo o se è stato necessario per risolvere il problema. –

+1

Ok, posso immaginare che sia necessario ricostruire completamente tutti i delta per sbarazzarsi dei pegni pendenti. – riezebosch

0

Rifondare nuovamente i tuoi commit potrebbe risolvere il problema. Se ciò non è di aiuto, puoi usare i comandi di basso livello git (git-cat-file) per vedere quale commit contiene questo strano oggetto ad albero, e ricostruire di aver inserito una versione corretta dell'albero senza i duplicati. Tuttavia, non sono a conoscenza di strumenti automatici che potrebbero essere in grado di risolvere il problema, e probabilmente dovrai modificare tutti gli alberi e gli oggetti commit che già collegano a quello strano.

A proposito, git ls-tree ee2060 dovrebbe mostrare ulteriori dettagli sui dati presenti nell'albero danneggiato, ad esempio i file a cui viene fatto riferimento.

1

checkout un nuovo ramo poco prima del commit problematico. ora controlla i file dal commit problematico. Ora aggiungili e confermali usando lo stesso messaggio (usa l'opzione -C). Ripeti per il resto dei commit. Al termine, reimpostare l'altro ramo in modo che punti a quello corretto. Puoi quindi spingere.

+0

Ok, ho controllato prima il problema e ho recuperato i commit in ordine, saltando i cattivi commit e ho resettato il master al nuovo ramo. Tuttavia, git fsck mostra ancora le voci duplicate, anche dopo aver provato tutto quello che potevo pensare per forzare la potatura, ecc. Come controllo di integrità, ho controllato prima che il problema fosse introdotto e rimosso tutti i commit dopo. Il problema è ancora lì. Così ho scritto uno script bash per cercare ricorsivamente alberi di commit per trovare l'albero cattivo, e non è referenziato da nessuno di essi. C'è un modo per ottenere git per potare oggetti senza riferimento che non conosco? –

+0

finché non hai alcun riferimento ai cattivi commit, li avrai persi. basta fare un 'git gc --aggressive --prune = now' una volta che i riferimenti sono stati ordinati a causa del reflog che non li ha più memorizzati nella cache. –

6

Ho usato git-replace e git-mktree per risolvere questo problema in passato. In pratica si mantiene l'oggetto ad albero rotto, ma si sostituiscono tutti i collegamenti e si fa puntare a un nuovo oggetto.

  1. In primo luogo abbiamo afferrare l'albero cattivo: git ls-tree bad_tree_hash > tmpfile.txt Questo scrive il vostro albero cattivo.Per esempio:

    040000·tree·3cdcc756ee0ed636c44828927126911d0ab28a18 → xNotAlphabetic 
    040000·tree·4ad0d8ef014b8cc09c95694399254eff43217bfb → EXT 
    040000·tree·d65085e4a05ea9ac8b79e37b87202dd64d402c2e → duplicateFolder 
    040000·tree·d65085e4a05ea9ac8b79e37b87202dd64d402c2e → duplicateFolder 
    040000·tree·fd0661d698ace91135a8473b26707892b7c89c32 → ToolTester 
    040000·tree·d65085e4a05ea9ac8b79e37b87202dd64d402c2e → duplicateFolder 
    

    NB, · & → sono spazi bianchi [spazio] e [scheda]

  2. Avanti, modificare il testo, eliminando le linee di offendere, e risparmia con terminazioni in stile Unix (cioè solo LF, non CRLF). Con questo esempio, facciamo questo:

    040000·tree·4ad0d8ef014b8cc09c95694399254eff43217bfb → EXT 
    040000·tree·d65085e4a05ea9ac8b79e37b87202dd64d402c2e → duplicateFolder 
    040000·tree·fd0661d698ace91135a8473b26707892b7c89c32 → ToolTester 
    040000·tree·3cdcc756ee0ed636c44828927126911d0ab28a18 → xNotAlphabetic 
    
  3. Tipo cat tmpfile.txt | git mktree che farà una nuova, oggetto albero fisso e salvarlo, e restituire il nuovo hash: a55115e4a05ea9ac8b79e37b872024d64d4r2c2e aka per scopi dimostrativi new_tree_hash

  4. Successivo git replace creerà un nuovo riferimento, che impone invece a tutti i link precedenti di utilizzare il nuovo oggetto fisso. git replace bad_tree_hash new_tree_hash

questo risolverà il tuo problema immediato. Se sei interessato, guarda il link prioritario nella cartella .git/refs/replace.


L'oggetto albero cattivo continuerà a generare avvisi ogni volta che si fa un controllo sul vostro repository con git fsck, ma può essere ignorata, e tutti i tuoi commit e altri link sarà coerente e lavorare indipendentemente.

1

Ho avuto un problema di questo tipo e tutte le soluzioni qui e in altri thread SO non è riuscito a risolverlo per me. Alla fine ho usato BFG repo cleaner per distruggere tutti i commit che fanno riferimento al nome della cartella errata, che probabilmente era eccessivo ma ha riparato con successo il repository.