MASTRILOالدورة/كيف يرى Git التاريخ؟
MASTRILO

كيف يرى Git التاريخ؟

تتبعنا في الدرس السابق علاقة الـ Parent من Commit إلى الذي سبقه:

text
Commit D
    │
    ▼
Commit C
    │
    ▼
Commit B
    │
    ▼
Commit A

في هذا المثال يبدو التاريخ كأنه خط واحد. لكنه لا يبقى كذلك عندما تتفرع منه مسارات مختلفة أو تلتقي هذه المسارات لاحقا.

من السلسلة إلى الرسم البياني

لنفترض أن لدينا هذا التاريخ:

text
Commit C
    │
    ▼
Commit B
    │
    ▼
Commit A

إذا بني Commit C و Commit D كل منهما على Commit B فسيشير كلاهما إلى الـ Parent نفسه:

text
Commit C       Commit D
    │              │
    └──────┬───────┘
           ▼
       Commit B
           │
           ▼
       Commit A

لم يعد التاريخ سلسلة واحدة. أصبحت لدينا عقد مرتبطة بأسهم. و قد تنطلق عدة أسهم نحو الـ Parent نفسه.

الرسم البياني للـ Commits (Commit Graph)

يمكننا النظر إلى كل Commit على أنه عقدة (Node) و إلى كل علاقة Parent على أنها سهم يصلها بعقدة سابقة:

text
Commit C       Commit D
    │              │
    └──────┬───────┘
           ▼
       Commit B

تشكل هذه العقد و العلاقات ما يسمى Commit Graph. و لا يحتاج Git إلى قائمة منفصلة ترتب كل الـ Commits فالعلاقات بينها تحدد طرق الرجوع في التاريخ.

لماذا يسمى DAG؟

قد تسمع أحيانا أن Git يعتمد على Directed Acyclic Graph أو اختصارا DAG.

  • Directed لأن كل علاقة تتجه من Commit إلى Parent سابق.
  • Acyclic لأن اتباع علاقات الـ Parent لا يمكن أن يعيدنا إلى الـ Commit الذي بدأنا منه.

يسجل الـ Commit معرفات الـ Parents عند إنشائه ثم يبقى الـ Object المخزن ثابتا. لو غيرنا Parent لاحقا لتغيرت بيانات الـ Commit و نتج معرف جديد. لذلك لا يمكن تعديل Commit سابق كي يشير إلى Commit جاء بعده و يغلق حلقة.

هذه العلاقات تتجه نحو الماضي:

text
Commit C
    │
    ▼
Commit B
    │
    ▼
Commit A

أما هذا الشكل فيصنع حلقة تعود إلى نقطة البداية:

text
Commit C
    │
    ▼
Commit B
    │
    ▼
Commit A
    │
    └─────────┐
              │
              ▼
           Commit C

لا يمكن أن تنتج هذه الحلقة من علاقات Parent سليمة ولذلك يوصف الرسم البياني بأنه Acyclic.

Commit C و Commit D يشيران إلى Commit B الذي يشير إلى Commit A مع منع سهم عائد يصنع حلقة
روابط Parent تتجه نحو الماضي و لا تسمح بتكوين حلقة داخل Commit Graph

كيف يقرأ Git التاريخ؟

عندما تعرض سجل المشروع باستخدام:

bash
git log

يبدأ Git افتراضيا من الـ Commit الحالي ثم يتبع جميع علاقات الـ Parent. لذلك لا يعرض بالضرورة كل Commit Object موجود في قاعدة البيانات، بل يعرض الـ Commits التي يمكن الوصول إليها من نقطة البداية.

git log يبدأ من Commit D و يتبع المسار إلى Commit B ثم Commit A بينما يبقى Commit C خارج المسار
يعرض git log الـ Commits التي يصل إليها عبر Parent من نقطة البداية

لنجرب بأنفسنا

الـ Terminal بجانبك يحتوي على مستودع فيه سلسلة من الـ Commits.

اعرض التاريخ المختصر:

bash
git log --oneline

انسخ المعرف المختصر لأول سطر و استخدمه مكان <commit-hash>:

bash
git cat-file -p <commit-hash>

انسخ المعرف الموجود في سطر parent و استخدمه مكان <parent-hash>:

bash
git cat-file -p <parent-hash>

كرر الأمر بالمعرف الجديد حتى تصل إلى Commit لا يحتوي على سطر parent.

الصورة الحالية

أصبح لدينا الآن نموذجان مترابطان:

text
Commit
├── Tree
│   └── Blob
└── Parent
    └── Commit

يقود معرف الـ Tree من الـ Commit إلى حالة الملفات، بينما تقود علاقات الـ Parent إلى Commits سابقة و تبني Commit Graph.

لكن الوصول إلى Commit ما زال يتطلب معرفا طويلا. في الدرس التالي سنتعرف إلى References التي تمنح هذه المعرفات أسماء يسهل استخدامها.

الفحص الآلي يؤكد أن الـ Commit الأول بلا parent. أما تتبع السلسلة فهو تمرين قراءة: قارن كل معرف تستخرجه بالمعرف الذي تقرأه في الخطوة التالية.

اختبر معلوماتك

سجّل دخولك للإجابة على الأسئلة وحفظ تقدّمك.

سجّل الدخول
اللوحات
نوع الخط
حجم الخط
أكملت 0 من 41 درس

Git Objects

7.كيف يرى Git التاريخ؟

Git on Your Machine1041 كيف يرى Git التاريخ؟مكافأة إكمال الدرس إضافة إلى نقاط أنشطته. 10 XP. تُمنح المكافأة مرة واحدة فقط.