2012-03-15 25 views
9

मैंने गिट और ज़िप फ़ाइलों के साथ एक अजीब समस्या में भाग लिया है। मेरी बिल्ड स्क्रिप्ट दस्तावेज एचटीएमएल पेजों का एक गुच्छा लेती है और उन्हें docs.zip में ज़िपित करती है, फिर मैं इस फ़ाइल को गिट में जांचता हूं।एक ही सामग्री को दो बार ज़िप करने से अलग-अलग SHA1 के साथ दो फाइलें क्यों मिलती हैं?

मेरी समस्या यह है कि हर बार जब मैं बिल्ड स्क्रिप्ट को फिर से चलाता हूं और एक नई ज़िप फ़ाइल प्राप्त करता हूं तो नई ज़िप फ़ाइल में पिछले रन की तुलना में एक अलग SHA1 होता है। मेरी बिल्ड स्क्रिप्ट चींटी ज़िप कार्य को बुला रही है। हालांकि मैक ओएस एक्स खोल से मैकोज़क्स ज़िप को मैन्युअल रूप से कॉल करने से मुझे एक अलग 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 को ज़िप फ़ाइल में शामिल किया जा रहा है।

ज़िप एल्गोरिदम निर्धारक है? यदि एक ही सामग्री पर चलते हैं तो क्या यह बिल्कुल वही बिट्स का उत्पादन करेगा? अगर नहीं तो क्यों नहीं?

फ़ाइलों को एक निश्चित तरीके से ज़िप करने के लिए मेरे विकल्प क्या हैं? ज़िप्ड अप फ़ाइल में उनमें से हजारों हैं, मुझे उम्मीद नहीं है कि उन फ़ाइलों को ज्यादा बदलना है। मुझे पता है कि गिट आपके द्वारा चेक की जाने वाली किसी भी फाइल को ज़िपित करेगा लेकिन उन्हें ज़िप करने की प्रेरणा सिर्फ उन लोगों के द्रव्यमान को दूर रखना है।

+2

दो चीजें। सबसे पहले ऐसा लगता है कि ज़िप फ़ाइल को ज़िप में शामिल किया जा सकता है क्योंकि यह एक ही निर्देशिका में है, जो गैर-निर्धारिती परिणाम दे सकता है। दूसरा ज़िप में तिथियां और समय शामिल हो सकते हैं जो रन से चलाने के लिए अलग होंगे। –

+0

ज़िप फ़ाइल को नए जेनरेट किए गए ज़िप में शामिल नहीं किया जा रहा है, मैंने जांच की है कि मैंने अपने प्रश्न पोस्ट करने से पहले। – ams

उत्तर

8

विकिपीडिया http://en.wikipedia.org/wiki/Zip_(file_format) के अनुसार लगता है कि ज़िप फ़ाइलों फ़ाइल अंतिम संशोधन समय के लिए शीर्ष लेख है और फ़ाइल अंतिम संशोधन दिनांक इसलिए किसी भी जिप Git में जाँच की फ़ाइल यदि जिप के बाद से एक ही सामग्री से पुनर्निर्माण किया गया है बदल दिया है git करने के लिए दिखाई देगा। और ऐसा लगता है कि उन शीर्षकों को सेट न करने के लिए यह बताने के लिए कोई ध्वज नहीं है।

मैं केवल टैर का उपयोग करने का सहारा ले रहा हूं, ऐसा लगता है कि एक ही इनपुट के लिए एक ही बाइट उत्पन्न होता है यदि कई बार चलाया जाता है।

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

आप लगातार एक ही हैश मिल जाएगा:

+0

यह सही है, ज़िप संग्रह में फ़ाइल संशोधन समय (और यूनिक्स - फ़ाइल अनुमतियों, मालिक, निर्माण समय और ईवेंट पहुंच समय के लिए) सहित विभिन्न फ़ाइल जानकारी शामिल है। –

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 विकल्प का उपयोग बचाता है।

बिना किसी के ऊपर प्रयास करें और आपको प्रत्येक बार एक अलग हैश देखना चाहिए।

+4

यह एक सही उत्तर है, लेकिन यदि आप उपयोगकर्ता को यह बताते हैं कि यह क्या करता है, और यह समस्या को हल करता है तो यह सहायक होगा। Gzip मदद से "-n -no-name संपीड़ित करते समय, मूल फ़ाइल नाम और समय स्टाम्प को डिफ़ॉल्ट रूप से सहेजें नहीं ..." सहेजे गए मूल फ़ाइल नाम हैंश को प्रभावित कर रहे थे। –