كيف ترتبط الـ Commits ببعضها؟
في الدرس السابق رأينا أن كل Commit يشير إلى حالة معينة من ملفات المشروع. لكن هذه الحالات ليست منفصلة عن بعضها. يمكن أن يحمل الـ Commit أيضا معرف Commit سابق. و يسمى هذا الحقل Parent Commit.
بداية التاريخ
لا يوجد شيء قبل أول Commit في المستودع لذلك لا يحتوي على Parent:
Commit Aيسمى هذا الـ Commit أحيانا Initial Commit.
إضافة Commit جديد
بعد تعديل الملفات و إنشاء Commit B، يسجل Git معرف Commit A في حقل الـ Parent:
Commit B
│
▼
Commit Aأصبح Commit A الآن Parent للـ Commit B. و من Commit B يستطيع Git الرجوع خطوة واحدة إلى الوراء.
بناء سلسلة من الـ Commits
في التاريخ الخطي، يشير كل Commit جديد إلى الـ Commit الذي كان قبله:
Commit D
│
▼
Commit C
│
▼
Commit B
│
▼
Commit Aيبدأ Git من Commit معين و يتبع حقول الـ Parent للوصول إلى ما سبقه. هذه العلاقات هي التي تعطي الـ Commits ترتيبها داخل التاريخ.
هذا الشكل الخطي هو أبسط الحالات. لا يحتوي أول Commit على أي Parent. و يحتوي الـ Commit العادي غالبا على Parent واحد، بينما يحتوي Merge Commit على أكثر من Parent. سنعود إلى الحالة الأخيرة عندما ندرس الدمج.
ماذا يحتوي الـ Commit فعليا؟
إلى جانب معرف الـ Tree و بيانات المؤلف و الرسالة، يمكن أن يحتوي الـ Commit على معرف Parent:
Commit
├── Tree
├── Author
├── Committer
├── Timestamps
├── Message
└── Parentعندما يريد Git الوصول إلى ما قبل Commit معين فإنه يقرأ معرف الـ Parent ثم يفتح الـ Commit المشار إليه.

كيف يقرأ Git التاريخ؟
لنفترض أن Git بدأ من Commit D. يقرأ معرف الـ Parent فيصل إلى Commit C:
Commit D
↓
Commit Cثم يكرر العملية:
Commit D
↓
Commit C
↓
Commit Bو يستمر حتى يصل إلى Commit لا يحتوي على Parent. لهذا يستطيع Git عرض التاريخ من أحدث Commit إلى أقدمه.

لنجرب بأنفسنا
الـ Terminal بجانبك يحتوي على مستودع فيه أكثر من Commit.
اعرض سجل الـ Commits:
git logانسخ معرف أول Commit في المخرج ثم استخدمه مكان <commit-hash>:
git cat-file -p <commit-hash>ابحث عن سطر parent ثم انسخ المعرف الموجود فيه و استخدمه مكان <parent-hash>:
git cat-file -p <parent-hash>ستظهر لك بيانات الـ Commit السابق و رسالة first.
الصورة الحالية
اكتملت الآن صورة الـ Objects الأساسية التي درسناها:
Blob
└── File Content
Tree
└── File Structure
Commit
├── Project Snapshot
└── Parent Referenceيحمل الـ Blob محتوى ملف. و يربط الـ Tree الأسماء بالـ Objects. و يشير الـ Commit إلى حالة المشروع. أما حقل الـ Parent فيقود إلى Commit سابق.
في الدرس التالي سنجمع هذه العناصر و نستكشف الـ Objects التي أنشأها Git داخل مستودع حقيقي.
الفحص الآلي يؤكد بيانات المستودع فقط. تحقق بنفسك من معرف parent و قارنه بمعرف الـ Commit الأول؛ ظهور علامة النجاح لا يثبت أنك تتبعت الرابط.