গিট কম্পিউট ফাইল হ্যাশ কীভাবে হয়?


124

গাছের বস্তুগুলিতে সংরক্ষিত SHA1 হ্যাশগুলি (ফিরে আসার সাথে git ls-tree) ফাইলের সামগ্রীর SHA1 হ্যাশগুলির সাথে মেলে না (যেমন ফিরে এসেছে sha1sum)

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

গিট কম্পিউট ফাইল হ্যাশ কীভাবে হয়? এটি হ্যাশ গণনার আগে বিষয়বস্তুকে সংকুচিত করে?



1
অধিক বিবরণের জন্য, তাও দেখতে progit.org/book/ch9-2.html
netvope

5
নেটভোপের লিঙ্কটি এখন মারা গেছে বলে মনে হচ্ছে। আমি মনে করি এই নতুন অবস্থানের হল: git-scm.com/book/en/Git-Internals-Git-Objects যা থেকে §9.2 git-scm.com/book
Rhubbarb

উত্তর:


122

গিট "ব্লাব" দিয়ে বস্তুর উপসর্গ করে, তার পরে দৈর্ঘ্য হয় (একটি মানব-পঠনযোগ্য পূর্ণসংখ্যার হিসাবে), তার পরে একটি এনওলির অক্ষর থাকে

$ echo -e 'blob 14\0Hello, World!' | shasum 8ab686eafeb1f44702738c8b0f24f2567c36da6d

সূত্র: http://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html


2
এটি উল্লেখ করার মতো বিষয়ও এটি "\ r \ n" "" \ n "এর সাথে প্রতিস্থাপন করে তবে একা" leaves r "বিচ্ছিন্ন পাতা দেয়।
ব্যবহারকারী420667

8
above উপরের মন্তব্যে সংশোধন: কখনও কখনও গিট নিজের প্রতিস্থাপন / অটোক্রোল্ফ সেটিংসের উপর নির্ভর করে উপরের প্রতিস্থাপনটি করে।
ব্যবহারকারী420667

5
আপনি এর আউটপুট সাথে এটি তুলনা করতে পারেন echo 'Hello, World!' | git hash-object --stdin--no-filtersকোনও ক্রল্ফ রূপান্তর ঘটে না তা নিশ্চিত করার জন্য orচ্ছিকভাবে আপনি নির্দিষ্ট করতে পারেন বা গিটকে (এছাড়াও @ ইউজার 420667) এর --path=somethi.ngমাধ্যমে নির্দিষ্ট ফিল্টারটি ব্যবহার করতে দিতে নির্দিষ্ট করতে পারেন gitattributes। আর -wআসলে করার ফোঁটা জমা দিতে .git/objects(যদি আপনি হয় একটি Git রেপো তে)।
টোবিয়াস কেইনজলার

সমতাটি প্রকাশ করা, বোঝার জন্য: echo -e 'blob 16\0Hello, \r\nWorld!' | shasum == echo -e 'Hello, \r\nWorld!' | git hash-object --stdin --no-filters এবং এটি \nএবং 15 এর সাথেও সমান হবে
পিটার ক্রাউস

1
echoআউটপুটে একটি নতুন লাইন সংযোজন করে, যা গিটকেও দেওয়া হয়। এজন্য এর 14 টি অক্ষর। কোনও নিউলাইন ছাড়াই প্রতিধ্বনি ব্যবহার করতে, লিখুনecho -n 'Hello, World!'
বোকে ভার্স্টিঘ

36

আমি কেবল উত্তরটি প্রসারিত করছি @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>ফাইল উপর নির্ভর করে।

দেখুন: গিট কমিট অবজেক্টের ফাইল ফর্ম্যাট কী?

এবং সব লোককে ধন্যবাদ!

কিন্তু অপেক্ষা করো! , আপনি কি লক্ষ্য করেছেন যে <filename>এটি হ্যাশ গণনার জন্য ব্যবহৃত একটি প্যারামিটার নয়? দুটি ফাইলে সম্ভাব্যত একই হ্যাশ থাকতে পারে যদি তাদের বিষয়বস্তুগুলি তারা তৈরির তারিখ এবং সময় এবং তাদের নাম একই রকম উদাসীন হয়। গিট অন্যান্য সংস্করণ নিয়ন্ত্রণ সিস্টেমের চেয়ে ভাল নাম পরিবর্তন করতে এবং পুনরায় নামকরণ করায় এটির একটি কারণ।

নিজে করুন (এক্সট্রা)

  • পদক্ষেপ filenamethe. একই ডিরেক্টরিতে আলাদা করে অন্য একটি খালি ফাইল তৈরি করুন
  • পদক্ষেপ your. আপনার উভয় ফাইলের হ্যাশগুলির সাথে তুলনা করুন।

বিঃদ্রঃ:

লিঙ্কটিতে কীভাবে treeঅবজেক্টটি হ্যাশ হয়েছে তা উল্লেখ করা হয়নি । আমি অ্যালগরিদম এবং প্যারামিটারগুলির বিষয়ে নিশ্চিত নই তবে আমার পর্যবেক্ষণ থেকে এটি সম্ভবত সমস্ত হ্যাশ blobsএবং তার trees(সম্ভবত তাদের হ্যাশগুলি) এর উপর ভিত্তি করে একটি হ্যাশ গণনা করে


SHA1("blob" + <size_of_file>- ব্লব এবং আকারের মধ্যে অতিরিক্ত স্থানের অক্ষর আছে? আকার দশমিক হয়? এটি কি শূন্য-উপসর্গযুক্ত?
osgx

1
@osgx আছে রেফারেন্স এবং আমার পরীক্ষার বিষয়টি নিশ্চিত করে। আমি উত্তর সংশোধন করেছি। আকারটি প্রিফিক্স ছাড়া পূর্ণসংখ্যা হিসাবে বাইটের সংখ্যা বলে মনে হয়।
স্যামুয়েল হারমার

13

git hash-object

এটি আপনার পরীক্ষা পদ্ধতি যাচাই করার একটি দ্রুত উপায়:

s='abc'
printf "$s" | git hash-object --stdin
printf "blob $(printf "$s" | wc -c)\0$s" | sha1sum

আউটপুট:

f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f
f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f  -

যেখানে sha1sumগনুহ Coreutils হয়।

তারপরে এটি প্রতিটি অবজেক্টের ধরণের বিন্যাস বোঝার জন্য নেমে আসে। আমরা ইতিমধ্যে তুচ্ছটি আবরণ করেছি blob, অন্যটি এখানে রয়েছে:


পূর্বের উত্তরে উল্লিখিত হিসাবে দৈর্ঘ্যটি বরং গণনা করা উচিত $(printf "\0$s" | wc -c)। যুক্ত খালি অক্ষর নোট করুন। অর্থাত, যদি স্ট্রিংটি 'এবিসি' থাকে তবে সামনের ফাঁকা অক্ষরটির দৈর্ঘ্য 4 হয়, 3 না পাওয়া যায় Then
মাইকেল

আপনি ঠিক বলেছেন তারা ম্যাচ করে। দেখে মনে হচ্ছে এখানে প্রতিধ্বনি পরিবর্তে প্রিন্টফ ব্যবহার করা থেকে কিছুটা ক্ষতিকারক পার্শ্ব প্রতিক্রিয়া রয়েছে। আপনি যখন 'abc' স্ট্রিং যুক্ত একটি ফাইলে গিট হ্যাশ-অবজেক্ট প্রয়োগ করেন আপনি 8 বাফ 1 বি ... f903 পাবেন যা আপনি প্রিন্টফের চেয়ে ইকো-ই ব্যবহার করার সময় পাবেন। প্রদত্ত যে প্রতিধ্বনি -e একটি স্ট্রিং শেষে একটি নতুন লাইন যুক্ত করে মনে হয় যে আচরণের সাথে প্রিন্টফের সাথে মেলে আপনি একই কাজ করতে পারেন (যেমন s = "$ s \ n")।
মাইকেল একোকা

3

লাইফ গ্রুইনওল্ড্ট উত্তরের উপর ভিত্তি করে , এখানে একটি শেল ফাংশন বিকল্প রয়েছে 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

3

পাইথন 3-তে কিছু ইউনিট পরীক্ষার জন্য আমার এটির দরকার ছিল তাই ভেবেছিলাম আমি এটি এখানে রেখে দিই।

def git_blob_hash(data):
    if isinstance(data, str):
        data = data.encode()
    data = b'blob ' + str(len(data)).encode() + b'\0' + data
    h = hashlib.sha1()
    h.update(data)
    return h.hexdigest()

আমি \nসর্বত্র লাইন এন্ডিংয়ের সাথে লেগে আছি তবে কিছু পরিস্থিতিতে গিট এই হ্যাশ গণনা করার আগে আপনার লাইন এন্ডিংগুলিও পরিবর্তন করতে পারে যাতে .replace('\r\n', '\n')আপনারও সেখানে প্রবেশের প্রয়োজন হতে পারে ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.