گیت و Three tree

خوب دوستان بعد از چندی و اندی رسیدم خدمتتون گفتم یه مطلبی در مورد گیت بنویسم انقدر این نصیر مقاله تو ویرگول داد که دیگه منم دلم خواست یه دو تا کلام بنویسم

از اونجایی که مطلب قبلیمو دوستان بدشون نیومد و گفتن چرت بدی نیست :دی به نظرم اومد یه کم بیشتر در مورد گیت بنویسم

حالا قصد دارم چنتا مطلب دیگه هم در مورد گیت بعدا بنویسم اگه عمری بود و حس و حالش دست داد

خوب این حرفا رو ولش کن بریم یه ضرب سراغ مطلب سرتون رو درد نیارم.

مطلبی که در ادامه میخونید میخواد اینو بگه که سه مرحله وجود داره تا فایل شما توی گیت بره و کامیت بشه

اول فایل رو میسازیم

بعد با add فایل رو stage میکنیم

بعد هم commit میکنیم

چیزی که میخونید توضیح بیشتر از عملکرد خود گیت هست و اینکه اون زیر میرا داره چیکار میکنه

توی گیت 3 مدل درخت وجود داره مثل این عکس

درخت Working Directory

اولیش که خیلی هم دم دستیه همون Working directory هستش. این همون فلدر اصلی هست که توش فایل ها رو کپی میکنیم. توش فلدر میسازیم و از این کارا میکنیم. وقتی یه کدی رو clone میکنیم یا وقتی روی یه برنچ checkout میکنیم گیت کدهای مربوط به اون برنچ رو میاره توی اینجا.

درخت Index

دومیش رو میگن index و بعضی ها هم بهش میگن Staging که هر کدوم یه نگاه متفاوت داره. ایندکس بیشتر اصطلاحیه که توسط توسعه دهنده های گیت استفاده میشه و به عملکرد این Tree اشاره داره. اما Staging بیشتر توسط کاربران این درخت استفاده میشه و بیشتر به کاربردش واسه اونا اشاره داره حالا وقتی جلو تر توضیح بدم متوجه میشید (یه نکته رو خدمتون بگم این مطلبی رو که دارم میگم برداشت خودم هستش در مورد این تفاوت)

بزارید اول از دیدگاه کارایی یه مرور بکنیم staging رو و بعد کامل Index رو توضیح میدم. وقتی ما تو گیت توی working directory یه فایلی رو اضافه کنیم میتونیم با دستور git add به گیت بگیم آقا من توی کامیت بعدی که بخوام بزنم قصد دارم این فایلو که بهت میگم هم توی کامیتم باشه.(اینطوری فکر نکنید که اگه فایله قبلا باشه اگه نزنید فایله پاک میشه از تو کامیت بعدی نه اینطوری نیست بلکه به گیت میگین آقا من میخوام این فایلو با محتویاتش توی کامیت بعدی ببرم) عملا میگیم آقا فایلو در وضعیت کنونیش ببر تو staging area.

بعد از اینکه این کارو کردید هر وقت کامیت بزنید دیگه فایله میره.این مفهوم Staging توی گیت هستش. بهش staging area هم میگن.

حالا بزارید بگم index چیه. ایندکس یه فایله توی فلدر git. که میشه به اون به عنوان یه جدول نگاه کرد این جدول یه سری رکورد داره که میگه هر فایلی در چه وضعیتی هست تو این stage و اینکه وقتی add میکنیم محتویات فایلو از توی working directory بر میداره و میزنه تو دیتابیس گیت و hash ساخته شده توسط دیتابیس گیت رو تو همین جدول میزاره(اگه دیتابیس گیت که میگم براتون گنگه یعنی مطلب منو در مورد Hash object رو نخوندین)

لینک زیر فرمت این فایلو آورده(البته فکر نکنم خیلی کاربردی باشه. خخخخخ)

https://git-scm.com/docs/index-format

درخت HEAD

قبل اینکه بخوام توضیح بدم HEAD چیه به نظرم لازمه که کامیت رو توضیح بدم که از نظر ساختاری چیه راستشو بخواین واسه دونستنش لازمه بفهمیم branch هم چیه دقیقا توی گیت.

کامیت در کل یه snapshot از index هستش به قولی آنی رو نشون میده :دی

وقتی کامیت میزنیم گیت یه کپی از وضعیت جدول ایندکس درست میکنه یا به عبارتی از ایندکس یه tree میسازه (منظورم از tree همونی هستش که توی مقاله hash object گفتم اگه یادتون باشه نوع داده ای 4 نوع بود blob و tree و commit و tag) در ادامه یه چیزای دیگه هم مثل اینکه کی کامیتو زده و پدر و مادر کامیت کینو از این چیزا میزنه در نهایت خود محتوای کامیت رو توی دیتابیس خودش ذخیره میکنه و یه hash میگیره

حالا branch چیه خیلی ساده اگه بگم یه فایل هست واسه هر branch توی گیت که مقدار اون hash ای رو که بالاتر گفتم واسه کامیت ساخته میشه رو توی خودش نیگر میداره.یعنی به زبون ساده تر میگه آقا آخرین کامیت چی بوده.

به زبون دیگه branch یه اشاره گر به کامیت هستش (وقتی آدرس hash کامیت رو نگه میداره توی خودش خوب یعنی داره بهش اشاره میکنه دیگه :دی)

پس تا اینجای کار با زبون الکن خودم زور زدم بتونم توضیح بدم که کامیت و branch چی هستن سعی هم کردم یه کم عمیق تر به مطلب نگاه کنیم

حالا وقتشه با دونستن این دو تا مورد واستون توضیح بدم که HEAD چی هست

مفهوم HEAD خیلی ساده هستش داره میگه الان کدوم کامیت هستش که checkout شده همین. در کل HEAD هم نوعی اشاره گر هستش. دو نوع دیتا توش میتونه قرار بگیره یا میگه آقا الان من به یه branch دارم اشاره میکنم یعنی الان مثلا روی master من checkout کردم یا اینکه دارم مستقیم به Hash یک کامیت اشاره میکنم که اصطلاحا به این حالت میگن HEAD تو حالت detached قرار داره یعنی الان لنگش رو هواس :دی

یه فایل توی git. وجود داره به نام HEAD اگه برید یه نگا ه بهش بندازید میبینید که در حالتی که روی یک branch گیت checkout کرده محتویات این فایل مثل زیر هستش

ref: refs/heads/master

و زمانی که HEAD رو detached کنید یعنی برید به صورت مجزا روی یک کامیت checkout کنید یه همچین چیزی میشه محتویات فایل HEAD

78809a98c28499e2a951873b02246d95e510c0cd

خوب یه مطلب دیگه بگم و یه لینک خوب هم بدم واسه مفهوم reference توی گیت و حرفامو تموم کنم دیگه

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

لینک بالا یه توضیح خیلی خوبی داده حتما بخونیدش

خوب حالا مطلب آخر چیه؟ آقا بابا اون دو تا درخت اول که گفتیم (Working tree و index) به خاطر اینکه ساختار درختی فایل رو نگهداری میکنن دقیقا ساختار درختی دارن ولی HEAD خدا وکیلی دیگه ساختار درختی نداره و فقط یه اشاره گره. پس چرا به اونم میگن درخت. چون این دوستان توی کامیونیتی گیت به ساختار لینک لیستی که توی commit ها وجود داره (هر کامیت یه parent داره) و در نهایت HEAD به صورت مستقیم به یه کامیت اشاره داره یا به هر حال به یه branch اشاره داره که اونم در نهایت به یه کامیت اشاره میکنه هم میگن درخت یعنی میگن میشه گفت linked list هم یه نوع درخت هست که فقط یه شاخه داشته باشه. اینطوری شده که به زور به اونم گفتن درخت که در نهایت به این سه محیط بگن Three tree که خوشگل بشه و باهاش حال کنن.

ببخشید دیگه اگه سرتون رو درد آوردم منتظر نظرتون هستم.