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


Answers

मैं @Leif Gruenwoldt द्वारा जवाब पर केवल विस्तार कर रहा @Leif Gruenwoldt और @Leif Gruenwoldt द्वारा प्रदान किए गए संदर्भ में @Leif Gruenwoldt

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

  • चरण 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> और <contents_of_file> फ़ाइल के आधार पर भिन्न होता है।

और सभी लोगों thats!

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

यह खुद करो (Ext)

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

ध्यान दें:

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

Question

SHA1 ट्री ऑब्जेक्ट्स में संग्रहीत हैश (जैसा कि git ls-tree द्वारा वापस किया गया) फ़ाइल सामग्री के SHA1 हैश से मेल नहीं खाता (जैसा sha1sum द्वारा वापस किया sha1sum )

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

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




Leif Gruenwoldt उत्तर के आधार पर, यहां एक गेट 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