برنامه نویسی

گیت و عملکرد داخلی آن

گیت و عملکرد داخلی آن

این پست مقدمه ای در مورد عملکرد داخلی GIT است. در اینجا ما بهتر خواهیم فهمید که اجرای آن چگونه کار می کند و دستورات اساسی که در زندگی روزمره استفاده می کنیم.

توصیه من این است که هنگام خواندن شما آنچه را که در اینجا منتقل می شود تمرین کنید.

امیدوارم از آن لذت ببرید خواندن خوب!

لوله کشی کماندوس و چینی

دستورات GIT به دو دسته تقسیم می شوند: لوله کشی و چینی. لوله کشی به دستورات سطح پایین و پرسلن دستورات سطح بالاتری اشاره دارد. دستورات چینی برای ما شناخته شده است: addبا commitبا clone، و غیره دستورات لوله کشی در زیر هود Git قرار دارند و معمولاً به صورت دستی مورد استفاده قرار نمی گیرند. با وجود این GIT با استفاده از دستورات چینی ، از دستورات لوله کشی استفاده فشرده می کند.

فهرست راهنما .git

بیایید با ابتدای همه چیز شروع کنیم. هنگامی که ما یک مخزن GIT جدید را با git init، git یک دایرکتوری ایجاد می کند .git با دایرکتوری ها و پرونده های زیر:

$ ls -F1 .git
config
description
HEAD
hooks/
info/
objects/
refs/
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

Aquivo description توسط GitWeb استفاده می شود. Aquivo config شامل تنظیمات خاص پروژه است. دایرکتوری info حاوی الگوهای جهانی است که نادیده گرفته می شوند و توسط آن ردیابی نمی شوند .gitignoreبشر دایرکتوری hooks اسکریپت های قلاب Contém.

حال بیایید به آنچه در این مقاله علاقه مند است ، برسیم. دایرکتوری objects این جایی است که تمام محتوایی که توسط GIT مدیریت می شوند ذخیره می شوند. دایرکتوری refs فروشگاه ها را به تعهدات (شاخه ها) ارجاع می دهد. سرانجام ، خاص HEAD این به شاخه فعلی است که برای تعهدات استفاده می شود. بیایید به طور مفصل ببینیم که چگونه GIT هر یک از این بخش ها را در داخل کار می کند.

git add اشمیه git commit

بیایید ببینیم چه اتفاقی می افتد وقتی که ما معمولاً با استفاده از دستورات چینی مانند git add اشمیه git commit:

$ echo "Hello, world!" > hello.txt
$ git add hello.txt
$ git commit -m "add hello.txt"
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

به یاد داشته باشید که من گفتم که تمام محتوای مدیریت شده توسط GIT در آن ذخیره می شود .git/object؟ بنابراین بیایید به آنچه در داخل بعد از تعهد ایجاد شده است نگاه کنیم:

$ find .git/objects/
...
.git/objects/af/5626b4a114abcb82d63db7c8082c3c4756e51b -- blob
.git/objects/ec/947e3dd7a7752d078f1ed0cfde7457b21fef58 -- tree
.git/objects/c6/2126fdb09e19fec4e71e0d9a4351784dab680e -- commit
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

توجه داشته باشید که پس از تعهد ، سه دایرکتوری ایجاد شد. هر دایرکتوری یک شیء GIT را نشان می دهد ، که در این حالت عبارتند از: حباب ، درخت و تعهد.

ذخیره اشیاء

قبل از ادامه ، درک این موضوع که چگونه GIT اشیاء خود را ذخیره می کند ، مهم است. همانطور که قبلاً گفته شد همه چیز در آن ذخیره شده است .git/objects/ و برای انجام این کار ، GIT از توابع هش استفاده می کند.

توابع هش داده شده با داده های اندازه پویا برای مقادیر اندازه ثابت نقشه برداری شده است. پیاده سازی های بد می توانند به راحتی منجر به برخورد شوند ، جایی که می توان دو داده با اندازه متفاوت را به همان هش نقشه برداری کرد.

هنگامی که ما قبلاً تعهد ایجاد کردیم ، دیدیم که سه شیء تولید شده است و همه با استفاده از یک عملکرد هش ایجاد شده اند. این به معنای نام های گسترده ای مانند مثلاً است 065c57718c8acfe576b5ea5358cf3a8f461c69e2بشر نام الگوریتم مورد استفاده GIT SHA-1 است. همچنین ، همانطور که محتوای اصلی هش نمی تواند بخواند ، از آن به عنوان کلید الگوریتم تراکم ZLIB استفاده می شود. این بدان معنی است که می توانیم بگوییم که GIT یک پایگاه داده با ارزش کلیدی است!

آخرین اطلاعات مهم این است که اگر محتوا یکسان باشد ، اما نه ، اشیاء حباب با همان هش تولید می شوند. این امر به این دلیل است که یک تعهد اطلاعات دیگری را برای ایجاد هش در نظر می گیرد.

شیء حباب

شیء Blob نشان دهنده هر محتوا است. در این حالت و رایج ترین مورد ، محتوای یک پرونده را نشان می دهد. برای ایجاد این شی از دستور لوله کشی استفاده خواهیم کرد git hash-object:

$ echo "Hello, Git!" > hello.txt
$ git hash-object -w hello.txt
670a245535fe6316eb2316c1103b1a88bb519334
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در اینجا اولین شیء است که توسط Git ایجاد شده است. توجه داشته باشید که این همان نوع شیئی است که قبلاً ایجاد شده بود که ما به روشی مشترک متعهد شدیم. گزینه -w نشان می دهد که git برای ذخیره این شیء در .git/objectsبشر ای hello.txt این نام پرونده است:

$ find .git/objects/
...
.git/objects/af/5626b4a114abcb82d63db7c8082c3c4756e51b -- blob
.git/objects/ec/947e3dd7a7752d078f1ed0cfde7457b21fef58 -- tree
.git/objects/c6/2126fdb09e19fec4e71e0d9a4351784dab680e -- commit
.git/objects/67/0a245535fe6316eb2316c1103b1a88bb519334 -- blob (novo)
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

یک دستور GIT وجود دارد که در آن می توانیم ببینیم محتوای اصلی هر شیء GIT چیست ، یعنی git cat-file:

$ git cat-file -p 670a245535fe6316eb2316c1103b1a88bb519334 
Hello, Git!
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

قبل از رفتن به موضوع بعدی ، ما بهتر است هش ایجاد شده توسط GIT را تجزیه و تحلیل کنیم. همانطور که توضیح داده شد GIT از SHA-1 برای ایجاد هش استفاده می کند. آیا می توانیم از یک الگوریتم SHA-1 یک هش معتبر ایجاد کنیم؟ پاسخ این است: بله!:

$ echo -e "Hello, Git!" | openssl sha1
e40153b3e43a5ed7fa00ce6bd7a576763b88dab2
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اما … مدتی صبر کنید ، همان هش نبود که توسط Git ایجاد شده است! چه اتفاقی افتاد؟ علاوه بر GIT ، محتوا را بر اساس محتوا ایجاد کنید ، اطلاعات مهمی را قبل از محتوای اصلی اضافه می کند. این محتوا از استاندارد پیروی می کند object-type {content-size}\0بشر بیایید این را در ابتدای محتوا اضافه کنیم و ببینیم آیا هش مساوی ایجاد می شود:

$ echo -e "blob 12\0Hello, Git!" | openssl sha1
670a245535fe6316eb2316c1103b1a88bb519334
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

حالا بله ، یک هش معتبر!

موضوع درخت

شیء درخت نمایانگر اشیاء مختلف حباب و/یا درختان دیگر است. این محتوای پرونده را ضبط می کند و اطلاعات بیشتری در مورد اشیاء Blob اضافه می کند. برای این شی دو دستور وجود دارد: git update-index اشمیه git write-tree:

فرمان git update-index اطلاعات مربوط به حافظه پنهان را اضافه کنید. در مورد ، 100644 این یک حق معمولی را نشان می دهد و همچنین نامی را به شیء حباب اضافه می کند که در این شیء درخت جدید درج شده است ، که معمولاً به پرونده ای که محتوا در آن است اشاره دارد.

$ git update-index --add --cacheinfo 100644 670a245535fe6316eb2316c1103b1a88bb519334 hello.txt
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در آخر ، بیایید دستور را اجرا کنیم git write-tree که در واقع یک درخت شی جدید ایجاد می کند. در این مرحله می توانیم قبل از اجرای آن ، چند اشیاء حباب را که می خواهیم اضافه کنیم git write-tree:

$ git write-tree
d3ec8a0f5950fb1f73ce0d1ed55cd6fa7afcdeb9
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

آماده اکنون ما یک شی دیگر ایجاد کرده ایم! ما می توانیم وارد شویم .git/objects/ این یک شیء دیگر ایجاد شده است:

$ find .git/objects/
...
.git/objects/af/5626b4a114abcb82d63db7c8082c3c4756e51b -- blob
.git/objects/ec/947e3dd7a7752d078f1ed0cfde7457b21fef58 -- tree
.git/objects/c6/2126fdb09e19fec4e71e0d9a4351784dab680e -- commit
.git/objects/67/0a245535fe6316eb2316c1103b1a88bb519334 -- blob (novo)
.git/objects/d3/ec8a0f5950fb1f73ce0d1ed55cd6fa7afcdeb9 -- tree (novo)
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اتهامات

این شیء یک تعهد را نشان می دهد ، این اطلاعات مفیدی است که برای شناسایی تغییراتی که ایجاد شده است استفاده می شود. برای این شی از دستور استفاده خواهیم کرد git commit-tree، آن را به عنوان یک پارامتر یک شیء درخت ، تعهد قبلی و پیام توصیف تعهد دریافت می کند:

$ git commit-tree d3ec8a0f5950fb1f73ce0d1ed55cd6fa7afcdeb9 -p bdacb9cd59348d39994e4cb392b734f9236bd859 -m "update hello.txt"
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ما باید از پارامتر آگاه باشیم -p که نشان دهنده تعهد قبلی است. این باید به عنوان تاریخچه تعهد با تعهد به تعهد قبلی مراجعه شود.

$ find .git/objects/
...
.git/objects/af/5626b4a114abcb82d63db7c8082c3c4756e51b -- blob
.git/objects/ec/947e3dd7a7752d078f1ed0cfde7457b21fef58 -- tree
.git/objects/bd/acb9cd59348d39994e4cb392b734f9236bd859 -- commit
.git/objects/67/0a245535fe6316eb2316c1103b1a88bb519334 -- blob (novo)
.git/objects/d3/ec8a0f5950fb1f73ce0d1ed55cd6fa7afcdeb9 -- tree (novo)
.git/objects/12/7f0bcadb277747bfa75cc14014c91941d26d94 -- commit (novo)
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

بله ، این یک شیء تعهد معتبر و همچنین موردی است که توسط git commitبشر حال ، اگر ما اجرا کنیم git log، ما چیز جالبی خواهیم دید:

$ git log
commit c62126fdb09e19fec4e71e0d9a4351784dab680e (HEAD -> main)
Author: Lucas 
Date:   Wed Mar 12 10:26:28 2025 -0300

    add hello.txt
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

دلیل فقط اولین تعهد ایجاد شده چیست؟ ساده: Refs! توجه داشته باشید که اولین تعهد به شعبه اشاره دارد main و در آخرین تعهد ما ساخته شده است ، به هیچ وجه هیچ اشاره ای به شعبه اضافه نمی کنیم mainبشر

منابع

از منابع استفاده می شود به گونه ای که چندین تعهد به همان زمینه اشاره دارد. برای افزودن مرجع ما main ما می توانیم از دستور استفاده کنیم git update-ref:

$ git update-ref refs/heads/main 127f0bcadb277747bfa75cc14014c91941d26d94
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

حالا ، بیایید اجرا کنیم git log برای دیدن رفتار خود:

$ git log
commit 127f0bcadb277747bfa75cc14014c91941d26d94 (HEAD -> main)
Author: Lucas 
Date:   Wed Mar 12 10:34:20 2025 -0300

    update hello.txt

commit c62126fdb09e19fec4e71e0d9a4351784dab680e
Author: Lucas 
Date:   Wed Mar 12 10:26:28 2025 -0300

    add hello.txt
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

به زودی ، ما یک شاخه هستیم main با اشاره به آخرین تعهد ساخته شده. به آن شاخه توجه داشته باشید main این فقط به آخرین تعهد ساخته شده اشاره دارد ، او به تعهدات قبلی اشاره نمی کند. به همین دلیل مهم و اساسی است که وقتی ما یک تعهد ایجاد می کنیم ، باید مرجع را به تعهد قبلی منتقل کنیم.

برای نشان دادن بهتر این عمل ، می توانیم با git cat-file که متعهد 127f0bcadb277747bfa75cc14014c91941d26d94 زمینه ای به نام دارد parent مراجعه به تعهد قبلی:

$ git cat-file -p 127f0bcadb277747bfa75cc14014c91941d26d94

tree d3ec8a0f5950fb1f73ce0d1ed55cd6fa7afcdeb9
parent c62126fdb09e19fec4e71e0d9a4351784dab680e
author Lucas  1741786460 -0300
committer Lucas  1741786460 -0300

update hello.txt
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

پایان

شرط می بندم که من هیچ ایده ای نداشتم که عملکرد داخلی GIT چقدر جالب باشد ، درست است؟ اما این همه چیز نیست! هنوز مطالب وجود دارد که در این مقاله به آن پرداخته نشده است ، مانند RefSpec ، پروتکل های انتقال ، متغیرهای محیط و موارد دیگر …

پس از اتمام این خواندن ، من اکیداً توصیه می کنم که به دنبال کتاب رایگان در وب سایت رسمی GIT به نام Pro Git باشید که در آن عملیات GIT از سطح اساسی به پیشرفته ترین آنها پرداخته می شود. برای این مقاله از پایه ای از فصل استفاده کردم: 10. Git Internalals

امیدوارم از آن لذت برده باشید و امیدوارم که این مقاله نمای گسترده تری از Git ارائه داده باشد. این به عنوان یک توصیه و ایده پروژه است ، و اجرای ساده GIT را به زبان مورد علاقه خود انجام می دهد.

مرا در شبکه های من دنبال کنید: X ، LinkedIn و GitHub.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا