نموذج عقلي لفهم Git
تطوير النموذج العقلي لـ Git من شجرة عادية إلى شجرة مزيّنة. فهم الفروع كزينة قابلة للنقل يجعل عمليات rebase والعمليات المعقدة سهلة الفهم.
ليس من الغريب تشبيه Git بشجرة فكثير من أوامر Git تحتوي الفاظ لها علاقة بالأشجار كـgit worktree و git branch. هذا النموذج العقلي يحتاج إلى تعديل سهل وبسيط لكي يصبح أفض.
إن محور تشبيه Git بشجرة هو الفروع (branches) وهذا التشبيه قد ينتج إلى توليد فهم أن الفروع في Git هي شيء صلب صعب التحريك والتحويل. الفروع في Git يسهل تحريكها وإعادة تشكيلها وذلك باستخدام تعليمات أو أوامر كـgit rebase و غيرها.
التعديل المطلوب لتطير هذا النموذج العقلي بسيط. فقط تخيل أن Git شجرة مزيّنة كأشجار أعياد الميلاد أو غيرها بدلا من مجر شجرة.
الفروع في Git هي مجرّد أسماء
أول تعديل على النموذج هو التفكير بفروع Git كمجرد أسماء. بإسقاط هذا على النموذج الجديد تكون الفروع هي بمثابة الزينة أو الأربطة المثبتة على نهاية الفروع. لو تم ربط شريط أحمر على نهاية فرع فمكن تسمية هذا الفرع بالفرع ذو الشريط الأحمر أو الفرع الأحمر اختصارا.
git branch red a1b2c3d4
الذي ينتج عن هذا التعديل هو أن الفروع يمكن نقلها ببساطة بحل الشريط ونقله إلى فرع آخر فيصبح الفرع الجديد هو الفرع ذو الشريط الأحمر أو الفرع الأحمر. من المهم أيضا فهم أن الفرع القديم لم يفنى. الفرع القديم موجود ولكنه بدون شريط زينة, بدون اسم.
git rebase main red
هذا المثال هو ما يحدث عند القيام بعملية git rebase. ما يحدث خلف الكواليس هو نمو فرع جديد بنفس محتوى الفرع القديم ومن ثم نقل الشريط أول الإسم من الفرع القديم إلى الفرع الجديد. الفرع القديم ما زال موجود ويمكن بكل بساطة العودة له باستخدام git reset --hard أو git branch -f مع إضافة العنوان القديم (commit sha) إلى الأمر.
المثال السابق يمثل النسبة الأكبر من اللبس في الفهم بين المبرمجين ولكن من الممكن أيضا عمل المزيد من الإسقاطات لفهم جوانب أخرى من Git.
الفرع الرئيسي أيضا مجرّد اسم
بينما فرغ أخي من كتابة برنامج من الصفر عن طريق الرفع مباشرة إلى الفرع الرئيسي طلب منه المشرف أن يعمل Pull Request لإتاحة مجال لعملية المراجعة الرسمية PR Review.
قد يبدو هذا سيناريو معقد للوهلة الأولى ولكن باستحضار النموذج الجديد يمكن إيجاد حل سهل. الفرع الرئيسي هو أيضا مجرد اسم مجرد شريط زينة ويمكن ببساطة نقله إلى أول Commit ومن إنشاء فرع أو اسم جديد على الموقع الحالي.
git branch first-branch main
git branch -f main <first commit>
يجدر التويه أنا هذا الحل يعتريه بعض النقص حيث أن محتوى أول commit لن يدخل في عملية المراجعة. يمكن إصلاح ذلك بإنشاء commit على فرع يتيم شجرة جديدة كما في المثال التالي.
مجموعة من الأشجار
في خضام مشروع توحيد code base لمشروعي الـAndroid والـiOS في ما يعرفي بـMonorepo, طلبت من أحد المهندسين جمع المشروعين مع ضرورة إبقاء تاريخ المشروعين كاملا.
هذا السيناريو قد يبدوا مروع ولكن ممكن حله ولكن أعترف انه ليس من الأمر السهل. الفكرة التي يجب استحضارها هنا أن git ليس من الضرورة أن يقتصر على شجرة واحدة فمن الممكن وجود مجموعة أشجار أو حتى فروع يتيمة.
تتطلب الخطوة الأولى تعريف repo جديد وربطه بكل من المشروعين اللآخرين ومن ثم سحب كل منهم في تفريعة خاصة. بالإسقاط على النموذج الجديد يمكن إعادة تسمية الفرع الرئيس لكل من المشروعين main-ios و main-android للإحتفاظ بإسم main للفرع الموحّد. اللآن يمكن مزج الفرع الرئيس لكل من المشروعين بفرع واحد.
ملاحظة: تستطيع الأشجار الإندماج بعملية تعرف باسم Inosculation أو التطعيم (إن صحّت ترجمتي).
ربما هذا السيناريو يستحق مقال كامل لذلك لن أخوض بتفاصيله, ولكن بالعودة إلى المثار السابق فمن الممكن إنشاء فرع يتيم بـcommit فارغ ومن ثم نقل الإسم main إلى هذا الفرع اليتيم الذي سيصبح الرئيسي. هذا السيناريو أيضا يستحق مقال خاص.
الخلاصة
يدور في خاطري أفكار لتطوير هذا النموذج وطرح مزيد من الإسقاطات ولكن أفضل في المرحلى الحالية إبقاء النموذج في نطاق السهل الممتنع فعملية التحول من نموذج شجرة إلى شجرة زينة أمر سهل التحقيق.