2012-03-15 66 views
9

我遇到了git和zip文件的一個奇怪問題。我的構建腳本需要一堆文檔html頁面,並將它們壓縮到docs.zip中,然後將該文件檢入到git中。爲什麼兩次壓縮相同的內容會給出兩個具有不同SHA1的文件?

我遇到的問題是,每次我重新運行構建腳本並獲取一個新的zip文件時,新的zip文件都具有與上一次運行不同的SHA1。我的構建腳本正在調用ant zip任務。然而,從Mac OS X shell中手動調用macOSX zip會給我一個不同的sha1,如果我壓縮兩次相同的目錄。

運行1:

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

運行2:

zip foo.zip * 
openssl sha1 foo.zip 

運行1和RUN2給出不同的SHA1即使內容沒有運行之間變化。在這兩種情況下,壓縮文件都會打印出完全相同的壓縮文件,並不表示像.DS_Store這樣的操作系統特定文件將被包含在壓縮文件中。

拉鍊算法是確定性的嗎?如果運行在相同的內容上,它會產生完全相同的位?如果不是爲什麼不呢?

我以確定性的方式壓縮文件有什麼選擇?壓縮文件中有成千上萬個文件,我不希望這些文件有太大的改變。我知道git會壓縮任何你簽入的文件,但是壓縮它們的動機是保持它們的質量。

+2

兩件事。首先,zip文件本身似乎可能包含在zip中,因爲它位於相同的目錄中,這可能會導致不確定的結果。其次,zip可能包含日期和時間,這些日期和時間將與運行時間不同。 – 2012-03-15 04:52:47

+0

zip文件未包含在新生成的zip中,我在發佈我的問題之前檢查了該文件。 – ams 2012-03-15 04:58:26

回答

8

根據維基百科http://en.wikipedia.org/wiki/Zip_(file_format)似乎zip文件有 文件的最後修改時間標題和文件的最後修改日期,以便籤入Git的任何zip文件會出現與git如果拉鍊是由因爲同樣的內容重建已經改變。而且似乎沒有標誌告訴它不設置這些標題。

我只是使用tar,它似乎產生相同的輸入多個相同的輸入字節。

+0

沒錯,ZIP歸檔文件包含不同的文件信息,包括文件修改時間(以及unix文件權限,所有者,創建時間和事件訪問時間)。 – 2013-04-23 12:22:42

7

默認情況下,Gzip已保存的文件名和時間戳

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

使用-n選項:

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

,你會始終得到相同的哈希值。

在沒有-n的情況下嘗試以上操作,每次都應該看到不同的散列值。

+4

這是一個正確的答案,但如果您告訴用戶它做了什麼以及它如何解決問題,這將會很有幫助。從gzip幫助「-n --no-name 壓縮時,默認情況下不保存原始文件名和時間戳...」 保存的原始文件名影響哈希。 – 2016-07-06 23:08:09

相關問題