[Git] गिट गणना फ़ाइल हैश कैसे करता है?


Answers

मैं केवल @Leif Gruenwoldt के उत्तर पर विस्तार कर रहा @Leif Gruenwoldt और @Leif Gruenwoldt द्वारा प्रदान किए गए http://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html में क्या है

यह स्वयं करो..

  • चरण 1. अपने भंडार में एक खाली पाठ दस्तावेज़ (नाम कोई फर्क नहीं पड़ता) बनाएँ
  • चरण 2. चरण और दस्तावेज़ को प्रतिबद्ध करें
  • चरण 3. git ls-tree HEAD निष्पादित करके ब्लॉब के हैश की पहचान करें
  • चरण 4. ब्लॉब का हैश e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
  • चरण 5. अपने आश्चर्य से बाहर निकलें और नीचे पढ़ें

जीआईटी अपनी प्रतिबद्धता हैश की गणना कैसे करता है

    Commit Hash (SHA1) = SHA1("blob " + <size_of_file> + "\0" + <contents_of_file>)

पाठ blob⎵ एक निरंतर उपसर्ग है और \0 भी निरंतर है और NULL चरित्र है। <size_of_file> और <size_of_file> फ़ाइल के आधार पर अलग-अलग होते हैं।

और वह सब लोग हैं!

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

यह स्वयं करें (एक्सटी)

  • चरण 6. एक ही निर्देशिका में एक अलग filename साथ एक और खाली फ़ाइल बनाएँ
  • चरण 7. अपनी दोनों फाइलों के हैंश की तुलना करें।

ध्यान दें:

लिंक का उल्लेख नहीं है कि tree वस्तु कैसे धोया जाता है। मैं एल्गोरिदम और पैरामीटर के बारे में निश्चित नहीं हूं, हालांकि मेरे अवलोकन से यह शायद सभी blobs और trees (उनके हैंश शायद) पर आधारित हैश की गणना करता है

Question

एसएचए 1 हैश पेड़ की वस्तुओं में संग्रहित है (जैसा कि git ls-tree द्वारा लौटाया गया है) फ़ाइल सामग्री के SHA1 sha1sum मेल नहीं खाता है (जैसा कि sha1sum द्वारा लौटाया गया है)

$ git cat-file blob 4716ca912495c805b94a88ef6dc3fb4aff46bf3c | sha1sum
de20247992af0f949ae8df4fa9a37e4a03d7063e  -

गिट गणना फ़ाइल हैश कैसे करता है? क्या यह हैश की गणना करने से पहले सामग्री को संपीड़ित करता है?




उत्तर के आधार पर, यहां git hash-object को git hash-object करने के लिए एक शेल फ़ंक्शन विकल्प है:

git-hash-object () { # substitute when the `git` command is not available
    local type=blob
    [ "$1" = "-t" ] && shift && type=$1 && shift
    # depending on eol/autocrlf settings, you may want to substitute CRLFs by LFs
    # by using `perl -pe 's/\r$//g'` instead of `cat` in the next 2 commands
    local size=$(cat $1 | wc -c | sed 's/ .*$//')
    ( echo -en "$type $size\0"; cat "$1" ) | sha1sum | sed 's/ .*$//'
}

परीक्षा:

$ echo 'Hello, World!' > test.txt
$ git hash-object test.txt
8ab686eafeb1f44702738c8b0f24f2567c36da6d
$ git-hash-object test.txt
8ab686eafeb1f44702738c8b0f24f2567c36da6d