آرش جعفرزاده
آرش جعفرزاده
خواندن ۴ دقیقه·۴ سال پیش

گیت و Hash Object

دوست دارم تو این متن یه کم بیشتر در مورد گیت بنویسم و شاید چیزایو که کمتر شنیده باشیم رو در موردش بگم

گیت خودش یه سایتی داره به اسم git-scm که به کمال تمام مواردی که توی این Source Control هست رو توضیح داده

اگه احساس میکنید هنوز با مفاهیمی مثل Commit ، Branch و یا Checkout تو گیت مشکل دارید پیشنهاد میکنم اون دکمه ضربدر بالا رو بزنید و از ادامه روزتون لذت ببرید

من قصد دارم خلاصه تر و به زبون فارسی یه مفهوم پایه ای رو که تو این سایت بهش Git Object میگه توضیح بدم. اگه میخوایین مطلب اصلی رو بخونید و حوصله چرت و پرت های منو ندارید لینک زیر رو استفاده کنید

https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

گیت کلا یه فایل سیستم هست که یه سری کانتنت توش با یه سری کلید (Hash) ایندکس شدن.حالا این یعنی چی؟!!

یعنی اینکه گیت یه دیتابیس هست که یه سری اطلاعات رو بهش میدی (مثلا فایل یا اگه برنامه نویس باشیم یه Byte Array) بعد اون یه Hash ازش میسازه و بعد اطلاعات و اون Hash رو ذخیره میکنه.

گیت به اینا که ذخیره میشه میگه Object.

هر وقت خواستیم با اون Hash میتونیم به اون اطلاعات دسترسی پیدا کنیم

گیت کلا اینه !! با یه سری کامند که از همین قابلیت پایه استفاده میکنن

واسه اینکه مطلب بالا رو بهتر تر متوجه شیم کامند های پایه ای که تو گیت میتونیم Content باهاش ذخیره کنیم بعدش دوباره بخونیم رو مینویسم

دستور hash-object کارش اینه که یه کانتنت رو به صورت فایل یا ورودی std in میگیره یه Hash واسش میسازه بعد تو همون دیتابیسی که گفتم ذخیره میکنه در نهایت هم اون Hash رو بر میگردونه

$ echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4

همینطور که میبینین تو دستور بالا test content رو به صورت ورودی به این دستور داده گیت هم ذخیرش کرده

دستور بعدی cat-file هستش این دستور برای گرفتن اطلاعات در مورد Object های ذخیره شده تو همون دیتابسیه هست که گفتم به مثال زیر دقت کنید

$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content

همون طور که میبینید وقتی که از این دستور استفاده میکنیم همون مقداری رو ذخیره کرده بودیم رو واسمون بر میگردونه

به صورت پیشفرض هم گیت همه این Object ها (اگه یادتون باشه گفتم گیت این اطلاعاتی که ذخیره میشرو اسمشو گذاشته Object) رو توی یه فولدری توی git. ذخیره میکنه به اسم objects

اگه بعد اجرای دستورا توی این فلدر برید یه فلدر دیگه هست 2 حرفی (6d) که دو تا حرف اول اون Hash توش قرار داره توی اون هم یه فایل هست با نام ما بقی hash و محتوای توش یه فایل Binary هست.

زمانی که داریم این Object ها رو ذخیره میکنیم یه Type هم میتونیم بهش بدیم این کار رو با سوییچ t- انجام میدیم

چهار نوع Object توی گیت وجود داره

اولیش blob هست. این نوع رو اگه سوییچ t- رو استفاده نکنیم به صورت پیشفرض سیستم انتخاب میکنه.

معنیش هم اینه که این Object دارای یه کانتن Binary هست. توی گیت تمام فایلها اگه بخوان به صورت Object ذخیره بشن (که میخوان :دی) با نوع blob ذخیره میشن

نوع بعدی رو بهش میگن tree . این نوع یه طورایی نقش Folder یا Directory رو توی File System داره تو مثال زیر یه نمونه این نوع Object هارو آوردم

040000 tree 219f68b0f53109cc1d8a726fd191d97fb7d29c50 aj
100644 blob 59e1e9879afcc40527d8f8c275932d1be6668d2a outer.txt

دقت کنید این نوع به صورت تکست ذخیره میشه و همینطوری که میبینید یه tree از یه سری خط تشکیل شده که هر کدوم شامل 4 بخش هست permissions (یه عدد طبق استاندارد های unix هست انگاری) ، object type (نوع داده آیتمی که زیر مجموعش هست) ، hash و File name.

نوع داده بعدی Commit هست که اونم قشنگ از اسمش معلومه چی هست.گیت وقتی یه کامیت رو میخواد ذخیره کنه از این فرمت استفاده میکنه. این مثال رو ببینین

tree c37142272b67e5c8d20b676113ac29b1f5e13a81
parent 90e1f792e12371e0014590668eb82dd661be3b73
author Arash Jafarzadeh <arashjfz@gmail.com> 1611859705 +0330
committer Arash Jafarzadeh <arashjfz@gmail.com> 1611859705 +0330

یه کامیت کلا توی گیت اینه: یه tree که اشاره به اونی که میدونیم میکنه (:دی) بعد میگه مادرم کیه (ممکنه بگه پدرمم کیه و اون زمانی هست که مرج میکنیم یعنی کامیت یه پدر داره یه مادر. الان ذهنتونو درگیر نکنید) در ادامه نویسنده و کسی که کامیت رو زده رو هم میگه (همون طور که میدونیم زمان کامیت زدن مثلا من میتونم بگم یکی دیگه نویسنده کامیته. راستشو بخواین میتونم بگم یکی دیگه کامیتو هم زده!!!)

به یه نکته توجه کنید که بعد parent یه hash اومده که نشون میده کامیت parent با چه hash ای ذخیره شده. در مورد tree هم همینطوره (کلا جناب لینوس به Pointer علاقه خاصی داشتن)

آخرین نوع هم tag هست. tag هم از نظر ذخیره سازی نوعش تکست هست (دقت کنید که تو پوشه objects به صورت binary ذخیره میشه و وقتی بر میگردونیمش تکست هست یعنی به صورت مفهومی گیت بهش به صورت تکست نگاه میکنه).

حالا این همه گفتم کلا چی هست. شما توی گیت دو مدل tag میتونید درست کنید.اولین مدل که tag ساده هستش فقط توی فایل ref مربوط به tag ، گیت Hash مربوط به کامیت رو ذخیره میکنه.اما یه مدل tag دیگه هم میشه توی گیت تعریف کرد که بهش میگن annotated tag. این مدل تگ ها دارای message و همچنین یه مفهومی هستن به اسم tagger که معادل همون commiter هستش (ولی اصغرشون :دی) یعنی کی تگ رو ساخته.اینا دیگه باید توی دیتابیس گیت واسه خودشون Object مخصوص خودشونو داشته باشن چون میخوان اطلاعات بیشتری رو ذخیره کنن

مثال زیر Object یه annotated tag رو نشون میده

object 17b9f3734abf1ec51a9fda56055379cb31207c5b
type commit
tag release/1.0.0
tagger Arash Jafarzadeh <arashjfz@gmail.com> 1611860185 +0330
Some tag message


امیدوارم مطالبی که نوشتم به دردتون خورده باشه چون من زمانی که با این مطالب خودم آشنا شدم خیلی حال خوبی داشتم.


گیتgitپیشرفتهhash
شاید از این پست‌ها خوشتان بیاید