2012-03-15 10 views
9

Ho incontrato uno strano problema con i file git e zip. Il mio script di compilazione prende un mucchio di pagine html di documentazione e li inserisce in un docs.zip quindi controllo questo file in git.Perché Zippare lo stesso contenuto due volte dà due file con SHA1 diverso?

Il problema che sto avendo è che ogni volta che rieseguire lo script di build e ottenere un nuovo file zip il nuovo file zip ha un SHA1 diverso rispetto alla precedente. Il mio script di build sta chiamando l'operazione ant zip. Tuttavia, chiamare manualmente il macOSX zip dalla shell di Mac OS X mi dà un sha1 diverso se io riavvolgo la stessa directory due volte.

Run 1:

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

Run 2:

zip foo.zip * 
openssl sha1 foo.zip 

Run 1 e run2 dare diverso SHA1 anche se il contenuto non è cambiato tra le esecuzioni. In entrambi i casi, zip stampa esattamente gli stessi file che vengono compressi, non indica che file specifici del sistema operativo come .DS_Store sono inclusi nel file zip.

L'algoritmo zip è deterministico? Se eseguito sullo stesso contenuto produrrà esattamente gli stessi bit? se no perché no?

Quali sono le mie scelte per zippare i file in modo deterministico? Ce ne sono migliaia nel file zippato, non mi aspetto che questi file cambino molto. So che git comprimerà tutti i file che si stanno registrando, ma la motivazione per comprimerli è semplicemente di toglierli dalla massa.

+2

Due cose. In primo luogo sembra che il file zip stesso potrebbe essere incluso nello zip poiché si trova nella stessa directory, il che potrebbe dare risultati non deterministici. In secondo luogo lo zip potrebbe includere date e orari che saranno diversi da esecuzione a corsa. Il file zip –

+0

non viene incluso nello zip appena generato, l'ho verificato prima di aver postato le mie domande. – ams

risposta

8

Secondo Wikipedia http://en.wikipedia.org/wiki/Zip_(file_format) sembra che i file zip hanno intestazioni per File la data dell'ultima modifica e il file data dell'ultima modifica in modo apparirà un file zip controllato in git a git essere cambiato se la zip è ricostruito dallo stesso contenuti da allora. E sembra che non ci sia una bandiera per dirgli di non impostare quelle intestazioni.

Sto usando solo tar, sembra che produca gli stessi byte per lo stesso input se eseguito più volte.

+0

Proprio così, l'archivio ZIP include diverse informazioni sui file, inclusi i tempi di modifica dei file (e per i permessi dei file unix, proprietario, ora di creazione e tempo di accesso agli eventi). –

7

Per impostazione predefinita, gzip salva il nome del file e la time stamp

%> 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 

Utilizzando l'opzione -n:

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

si costantemente ottenere lo stesso hash.

Provare sopra senza -n e si dovrebbe vedere un diverso hash ogni volta.

+4

Questa è una risposta corretta, ma sarebbe utile se si comunica all'utente come funziona e in che modo risolve il problema. Dalla gzip help "-n --no-name Durante la compressione, non salvare il nome del file originale e il timestamp di default ..." I nomi dei file originali salvati stavano influenzando l'hash. –