2012-06-07 6 views
7

Tuve problemas con algunos problemas de final de línea con 20 commits de vuelta y pasaron cosas raras. Ahora GIT espectáculos fsck:git tree contiene entradas de archivos duplicados

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

y mostrar git ee2060 muestra:

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

Esto me impide empujar al mando a distancia. git push muestra:

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' 

He intentado volver a embalar y recoger la basura. ¿Como puedo resolver este problema?

Respuesta

4

finalmente fija el repositorio de la siguiente manera

  1. hacer un clon fresco de GitHub, que sólo incluye confirmaciones antes de que ocurriera el problema
  2. Añadir mi mal estado de recompra desde el sistema de archivos como un mando a distancia en el nuevo clon
  3. cuidadosamente revisar comete de la mala cesión temporal en la copia de trabajo del nuevo clon

    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 cada uno, a su vez, copiar manualmente el mensaje de confirmación desde el otro repo
  5. eliminar el repositorio corrupta de mandos a distancia
  6. basura recoger + podar

    git gc --aggressive --prune=now 
    
  7. llorar feliz como fsck git no muestra las entradas del archivo duplicados
+0

¿Por qué sugerir --aggressive? Lo único que hace es ignorar toda la información delta recopilada anterior. Más información: http://metalinguist.wordpress.com/2007/12/06/the-woes-of-git-gc-aggressive-and-how-git-deltas-work/ – riezebosch

+0

@riezebosch No recuerdo por qué Incluí: agresivo o si se requería o no para solucionar el problema. –

+1

De acuerdo, me imagino que es necesario reconstruir por completo todos los deltas para deshacerse de los commit pendientes. – riezebosch

0

Al volver a establecer las confirmaciones puede solucionarlo. Si eso no ayuda, entonces puedes usar los comandos de bajo nivel de git (git-cat-file) para ver qué commits contiene este extraño objeto de árbol, y reconstruir allí una versión correcta del árbol sin los duplicados. Sin embargo, no conozco ninguna herramienta automática que pueda solucionar esto, y probablemente deba cambiar todo el árbol y el objeto de confirmación que ya tiene un enlace al extraño.

Por cierto, git ls-tree ee2060 debería mostrarle más detalles sobre los datos que están en el árbol dañado, como los archivos que se mencionan allí.

1

comprobación una nueva rama justo antes de la confirmación problemática. ahora revisa los archivos de la confirmación problemática. Ahora agréguelos y compromételos usando el mismo mensaje (use la opción -C). Repita para el resto de las confirmaciones. Cuando hayas terminado, restablece la otra rama para señalar esta correcta. Luego puedes empujar.

+0

Ok, revisé antes el problema y seleccioné cuidadosamente las confirmaciones en orden, omitiendo las malas confirmaciones y reiniciando el maestro a la nueva rama. Sin embargo, git fsck aún muestra las entradas duplicadas, incluso después de probar todo lo que se me ocurrió para forzar la poda, etc. Como comprobación de cordura, me retiré antes de que se presentara el problema y eliminé todos los commits posteriores. El problema sigue ahí. Así que escribí un script bash para buscar recursivamente los árboles de commit para encontrar el árbol malo, y no hace referencia a ninguno de ellos. ¿Hay alguna manera de hacer git para podar objetos sin referencia que yo no sepa? –

+0

, siempre y cuando no tenga ninguna referencia a los compromisos incorrectos, los eliminará. simplemente haga un 'git gc --aggressive --prune = now' una vez que sus referencias estén ordenadas debido a que el reflog ya no las almacena en la memoria caché. –

6

He usado git-replace y git-mktree para solucionar esto en el pasado. Básicamente, conserve el objeto de árbol roto, pero anule todos los enlaces y haga que apunten a un nuevo objeto.

  1. Primero agarrar el árbol malo: git ls-tree bad_tree_hash > tmpfile.txt Esto escribe a cabo su mal árbol.Por ejemplo:

    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, · & → son espacios en blanco [espacio] y [Tab]

  2. A continuación, editar el texto, la eliminación de las líneas ofensivas y guardar con terminaciones estilo Unix (es decir, solo LF, no CRLF). Con este ejemplo, hacemos esto:

    040000·tree·4ad0d8ef014b8cc09c95694399254eff43217bfb → EXT 
    040000·tree·d65085e4a05ea9ac8b79e37b87202dd64d402c2e → duplicateFolder 
    040000·tree·fd0661d698ace91135a8473b26707892b7c89c32 → ToolTester 
    040000·tree·3cdcc756ee0ed636c44828927126911d0ab28a18 → xNotAlphabetic 
    
  3. Tipo cat tmpfile.txt | git mktree lo que hará que un nuevo, objeto de árbol fijo y guardarlo, y devolver la nueva almohadilla: a55115e4a05ea9ac8b79e37b872024d64d4r2c2e alias para fines de demostración new_tree_hash

  4. Siguiente git replace creará una nueva referencia, que obliga a todos los enlaces anteriores a incidentes a usar el nuevo objeto fijo en su lugar. git replace bad_tree_hash new_tree_hash

Esto va a resolver su problema inmediato. Si le interesa, mire el enlace de anulación en la carpeta .git/refs/replace.


El objeto de árbol malo va a seguir generando advertencias cada vez que haces un control sobre su repositorio con git fsck, pero puede ser ignorada, y todas sus confirmaciones y otros enlaces será consistente y trabajar independientemente.

1

Tuve un problema de este tipo y todas las soluciones aquí y en otros hilos SO no pudieron solucionarlo. Al final usé BFG repo cleaner para destruir todas las confirmaciones que hacen referencia al nombre de la carpeta incorrecta, que probablemente fue exagerada pero reparó con éxito el repositorio.

Cuestiones relacionadas