2012-03-15 14 views
9

Me he encontrado con un problema extraño con los archivos git y zip. Mi script de construcción toma un montón de documentación en páginas html y las comprime en un archivo docs.zip. Luego miro este archivo en git.¿Por qué Zipping el mismo contenido dos veces da dos archivos con SHA1 diferente?

El problema que tengo es que cada vez que vuelvo a ejecutar el script de compilación y obtengo un nuevo archivo zip, el nuevo archivo zip tiene un SHA1 diferente al de la ejecución anterior. Mi script de construcción está llamando a la tarea zip de hormiga. Sin embargo, llamar manualmente al zip de macOSX desde el shell de Mac OS X me da un sha1 diferente si cierro el mismo directorio dos veces.

Ejecutar 1:

zip foo.zip * 
openssl sha1 foo.zip 
rm foo.zip 

Run 2:

zip foo.zip * 
openssl sha1 foo.zip 

la Prueba 1 y Run2 dar diferentes SHA1 a pesar de que el contenido no ha cambiado entre ejecuciones. En ambos casos, zip imprime exactamente los mismos archivos que se comprimen, no indica que se estén incluyendo archivos específicos del sistema operativo como .DS_Store en el archivo comprimido.

¿El algoritmo de zip es determinista? Si se ejecuta en el mismo contenido, ¿producirá exactamente los mismos bits? ¿si no, porque no?

¿Cuáles son mis opciones para comprimir los archivos de una manera determinista? Hay miles de ellos en el archivo comprimido, no espero que esos archivos cambien demasiado. Sé que git cerrará todos los archivos que registras pero la motivación para comprimirlos es mantener a la mayoría de ellos fuera del camino.

+2

Dos cosas. En primer lugar, parece que el archivo zip en sí mismo podría estar incluido en el archivo zip, ya que está en el mismo directorio, lo que podría dar resultados no deterministas. En segundo lugar, el zip puede incluir fechas y horas que serán diferentes de ejecutar para ejecutar. –

+0

archivo zip no está incluido en el código postal recién generado, lo compré antes de publicar mis preguntas. – ams

Respuesta

8

Según Wikipedia http://en.wikipedia.org/wiki/Zip_(file_format) parece que los archivos zip tienen cabeceras para de archivo Tiempo de la última modificación de fichero y la última fecha de modificación por lo que cualquier archivo zip se registró en git aparecerá a git haber cambiado si la cremallera se reconstruye desde el mismo contenido desde entonces. Y parece que no existe una bandera que le diga que no establezca esos encabezados.

Estoy recurriendo a simplemente usar tar, parece producir los mismos bytes para la misma entrada si se ejecuta varias veces.

+0

Correcto, el archivo ZIP incluye información de archivo diferente, incluida la hora de modificación del archivo (y para Unix - permisos de archivo, propietario, hora de creación y hora de acceso al evento). –

7

Por defecto, gzip guarda el nombre del archivo y el sello de tiempo

%> gzip -help 2>&1 | grep -e '-n' 
-N --name   save or restore original file name and time stamp 
-n --no-name   don't save original file name or time stamp 

%> gzip -V 
Apple gzip 272 

El uso de la opción -n:

%> tar cv foo/ | gzip -n > foo.tgz; shasum foo.tgz # sha256sum on Ubuntu 

obtendrá siempre el mismo hash.

Pruebe arriba sin -n y debería ver un hash diferente cada vez.

+4

Esta es una respuesta correcta, pero sería útil si le dice al usuario qué hace y cómo resuelve el problema. Desde la ayuda de gzip "-n --no-name Al comprimir, no guarde el nombre del archivo original y la marca de tiempo de forma predeterminada ..." Los nombres de archivo originales guardados estaban afectando al hash. –

Cuestiones relacionadas