مسارات عمل Git: ‏Git Flow وGitHub Flow وTrunk-Based Development

يوفر Git الفروع والالتزامات وعمليات الدمج والعلامات والمستودعات البعيدة وأدوات إعادة كتابة السجل. لكنه لا يقرر كيف ينبغي للفريق الجمع بينها. يعود هذا القرار إلى مسار عمل المشروع.

يحدد مسار عمل Git كيفية انتقال العمل من فكرة إلى بيئة الإنتاج. ويجيب عن أسئلة مثل: من أين ينشئ المطور فرعًا؟ كم يمكن أن يبقى الفرع مفتوحًا؟ ما الاختبارات التي يجب أن تنجح؟ من يراجع التغيير؟ كيف يُدمج؟ أين تُجهز الإصدارات؟ كيف تُرسل الإصلاحات العاجلة إلى الإنتاج؟ وما الفروع المحمية؟

مسار العمل الصحيح ليس المسار الذي يحتوي على أكبر عدد من الفروع أو أشهر مخطط. بل هو أبسط نموذج يدعم وتيرة تسليم المنتج، والتزامات الإصدارات، وحجم الفريق، ونضج الاختبارات، ومتطلبات الامتثال، ومسؤوليات الصيانة.

يشرح هذا الدليل عائلات مسارات العمل الرئيسية، بما فيها فروع الميزات وGitHub Flow وGit Flow واستراتيجيات الفروع بأسلوب GitLab وtrunk-based development ومسار عمل forking. كما يوضح كيف تؤثر طرق الدمج وCI/CD وfeature flags وفروع الإصدارات وحماية الفروع في النتيجة الفعلية.

ما الذي ستتعلمه؟

  • ما الذي يتحكم فيه مسار عمل Git وما الذي لا يتحكم فيه Git نفسه.

  • الفرق بين استراتيجية الفروع ومسار تسليم متكامل.

  • كيف يعمل Centralized Workflow وFeature Branch Workflow.

  • كيف يدعم GitHub Flow تعاونًا خفيفًا مبنيًا على pull requests.

  • كيف ينظم Git Flow التطوير والإصدارات والإصلاحات العاجلة.

  • لماذا لا يكون Git Flow مناسبًا تلقائيًا لتطبيقات الويب ذات التسليم المستمر.

  • كيف يحافظ trunk-based development على تكامل متكرر وفروع قصيرة العمر.

  • كيف يمكن وجود فروع إصدار من دون تحولها إلى فروع تطوير طويلة الأمد.

  • كيف يدعم Forking Workflow المساهمين الخارجيين.

  • كيف تغير merge commits وsquash merges وrebase شكل السجل.

  • كيف تطبق حماية الفروع والاختبارات الآلية ومراجعة الشيفرة وفحوص النشر مسار العمل.

  • كيفية اختيار مسار عمل لمشروع حقيقي وتوثيقه.

ما مسار عمل Git؟

مسار عمل Git هو اتفاق قابل للتكرار لإنشاء التغييرات ومراجعتها ودمجها وإصدارها وصيانتها داخل مستودع Git.

قد يحدد:

  • الفروع طويلة العمر، إن وُجدت.

  • المكان الذي يبدأ منه العمل الجديد.

  • كيفية تسمية فروع الميزات وإصلاح الأخطاء.

  • ما إذا كان المطورون يدفعون مباشرة إلى الفرع الرئيسي.

  • متى تكون pull requests أوmerge requests مطلوبة.

  • ما الفحوص الآلية التي يجب أن تنجح.

  • كيفية جمع الموافقات.

  • طريقة الدمج المسموح بها.

  • المكان الذي تُنشأ فيه الإصدارات.

  • كيفية تطبيق علامات الإصدارات.

  • كيفية التعامل مع hotfixes وbackports.

  • متى تُحذف الفروع المكتملة.

لذلك فإن مسار العمل أوسع من مخطط للفروع. قد يُظهر المخطط main وdevelop وفروع الميزات والإصدارات، لكنه لا يوضح ما إذا كانت الاختبارات إلزامية، أو المراجعات غير متزامنة، أو كيفية نشر database migrations، أو كيفية إخفاء الميزات غير المكتملة.

الفرق بين Git Workflow وGitHub Actions Workflow

تُستخدم كلمة workflow بطريقتين مرتبطتين لكن مختلفتين.

  • Git workflow: العملية البشرية والتقنية المستخدمة لتنظيم الفروع والالتزامات والمراجعات والدمج والإصدارات.

  • GitHub Actions workflow: عملية آلية تُعرّف في ملف YAML وتُشغّل بواسطة أحداث المستودع.

قد يتطلب مسار عمل Git عملية GitHub Actions أوGitLab CI/CD أوJenkins أوpipeline أخرى. تفرض الـpipeline جزءًا من عملية التطوير الأوسع، لكنها ليست استراتيجية الفروع كاملة.

لا يوجد مسار عمل واحد هو الأفضل للجميع

تختلف احتياجات فريق ويب صغير ينشر عدة مرات يوميًا عن تطبيق سطح مكتب يدعم ثلاثة إصدارات قيد الصيانة. كما تختلف متطلبات الصلاحيات في مكتبة مفتوحة المصدر عن مستودع شركة خاص. وقد يحتاج منتج خاضع للتنظيم إلى موافقات رسمية لا يحتاجها مشروع شخصي.

ينبغي أن يعكس مسار العمل أسئلة مثل:

  • كم مرة يُصدر المنتج؟

  • هل يمكن للإنتاج استقبال التغييرات باستمرار؟

  • هل تُصان عدة إصدارات منشورة في الوقت نفسه؟

  • ما مدى موثوقية وسرعة مجموعة الاختبارات؟

  • هل يمكن إخفاء الوظائف غير المكتملة باستخدام feature flags؟

  • كم مطورًا يساهم في المشروع؟

  • هل يُوثق بالمساهمين لمنحهم صلاحية الكتابة؟

  • هل تتطلب المؤسسة فصلًا بين المهام؟

  • هل يمكن إصلاح فشل النشر بسرعة باستخدام fix-forward؟

  • هل يجب أن تمر الإصدارات بمرحلة اعتماد أو استقرار؟

ينبغي للتعقيد أن يحل قيدًا فعليًا. فكل فرع دائم إضافي ينشئ عملًا متعلقًا بالمزامنة والسياسات والأتمتة والصيانة.

اللبنات الأساسية المشتركة بين معظم مسارات العمل

رغم اختلاف أسماء مسارات العمل، تستخدم معظم عمليات Git الحديثة اللبنات نفسها.

فرع افتراضي مستقر

يُسمى الفرع الافتراضي عادة main. وتتوقع الفرق غالبًا أن يكون محميًا وفي حالة معروفة، مثل أن يكون قابلًا للنشر أو الإصدار، أو على الأقل مدمجًا ومختبرًا.

التزامات قصيرة ومركزة

ينبغي أن تمثل الالتزامات تغييرات منطقية مفهومة. وتحسن الالتزامات المركزة المراجعة والتراجع وتصحيح الأخطاء وcherry-picking والتحليل التاريخي.

فروع للعمل المعزول

يوفر الفرع خط تطوير منفصلًا. والسؤال المهم في مسار العمل ليس ما إذا كانت الفروع موجودة، بل مدة بقائها والمكان الذي تُدمج فيه.

مراجعة الشيفرة

توفر pull requests وmerge requests مكانًا لمناقشة التغييرات وفحص الفروقات وطلب التحسينات وتسجيل الموافقة.

التحقق الآلي

تقلل الاختبارات وlinting والتحليل الأمني وفحص الأنواع وعمليات البناء وفحوص migrations وdeployment previews من خطر دمج تغييرات معطلة.

تحديد الإصدارات

تربط العلامات وسجلات الإصدارات ومعرّفات البناء وبيانات النشر الوصفية سجل المصدر بالملفات المسلّمة.

حماية الفروع

يمكن لمنصة الاستضافة منع عمليات الدفع المباشر وطلب الموافقات والفحوص الناجحة وتقييد force push والتحكم بمن يمكنه الدمج.

مسار العمل 1: Centralized Workflow

يحاكي Centralized Workflow نموذج المستودع المركزي التقليدي مع استخدام Git.

يستنسخ جميع المطورين مستودعًا مشتركًا واحدًا ويدمجون التغييرات في فرع رئيسي واحد:

A---B---C---D  main

يمكن للمطورين إنشاء الالتزامات محليًا، والمزامنة مع remote، وحل التباعد، والدفع إلى الفرع المشترك.

العملية الأساسية

  1. استنسخ المستودع المشترك.

  2. حدّث الفرع المحلي main.

  3. أنشئ التغييرات والالتزامات محليًا.

  4. ادمج تغييرات remote الأحدث عند الحاجة.

  5. ادفع إلى الفرع المشترك.

المزايا

  • تكلفة منخفضة جدًا لإدارة الفروع.

  • سهولة الاستخدام للمطور الفردي أو الفريق الصغير الموثوق.

  • نموذج ذهني خطي بسيط.

  • مناسب للمستودعات التي نادرًا ما تتداخل فيها التغييرات.

المخاطر

  • قد تتجاوز عمليات الدفع المباشر المراجعة.

  • قد يؤثر التزام معطّل في الجميع فورًا.

  • ينشئ العمل المتزامن تعارضات push وضغطًا للدمج بسرعة.

  • يوفر عزلًا محدودًا للعمل غير المكتمل.

  • يصعب تدقيق الموافقات من دون طبقة مراجعة إضافية.

متى يكون مناسبًا؟

قد يعمل هذا النموذج للمستودعات الشخصية ومشاريع التوثيق الصغيرة والنماذج الأولية المؤقتة أو لفريق صغير جدًا يملك تحققًا آليًا قويًا.

في معظم مشاريع البرمجيات الجماعية، يوفر مسار مراجعة مبني على feature branches أوtrunk-based تحكمًا أفضل.

مسار العمل 2: Feature Branch Workflow

ينشئ Feature Branch Workflow فرعًا منفصلًا لكل ميزة منطقية أو إصلاح خطأ أو إعادة هيكلة أو تغيير في التوثيق.

          C---D  feature/task-search
         /
A---B---E---F    main

يُراجع فرع الميزة ثم يُدمج في main.

العملية الأساسية

git switch main
git pull --ff-only
git switch -c feature/task-search

# عدّل الملفات
git add -p
git commit -m "إضافة مطابقة الكلمات المفتاحية للمهام"

git push -u origin feature/task-search

يفتح المطور pull request أوmerge request. وبعد المراجعة ونجاح الفحوص، يُدمج الفرع ويُحذف.

المزايا

  • يبقى العمل غير المكتمل معزولًا عن الفرع الافتراضي.

  • يمنح كل فرع المراجعين وحدة نقاش مركزة.

  • يمكن تشغيل الفحوص الآلية قبل الدمج.

  • يستطيع عدة مطورين العمل باستقلالية.

  • يمكن للفرع الافتراضي رفض عمليات الدفع المباشر.

المخاطر

  • تراكم الفروع طويلة العمر تباعدًا كبيرًا.

  • يصعب مراجعة pull requests الكبيرة.

  • يكشف الدمج المتأخر التعارضات وعدم التوافق المعماري.

  • قد تتحول الفروع إلى بيئات دائمة غير رسمية.

  • قد تخلط الفرق بين “وجود الفرع” و“تقدم الميزة بأمان”.

أفضل ممارسة

حافظ على فروع الميزات صغيرة وقصيرة العمر. ينبغي أن يمثل الفرع تغييرًا واحدًا قابلًا للمراجعة، لا مشروعًا يستمر ربع سنة كاملًا.

مسار العمل 3: GitHub Flow

GitHub Flow مسار عمل خفيف مبني على الفروع، ويتمحور حول فرع افتراضي محمي وpull requests.

تسلسله المعتاد:

  1. أنشئ فرعًا من الفرع الافتراضي.

  2. أنشئ التزامات مركزة.

  3. ادفع الفرع.

  4. افتح pull request، وربما تكون draft.

  5. ناقش التغيير وراجعه.

  6. شغّل الفحوص الآلية.

  7. ادمج بعد الموافقة.

  8. انشر النتيجة المدمجة وفق عملية المشروع.

  9. احذف الفرع المكتمل.

لا يتطلب النموذج فرع develop دائمًا.

             feature/a
            /         \
A---B---C---D-----------E---F  main

أوامر عملية لـ GitHub Flow

git switch main
git fetch origin
git merge --ff-only origin/main

git switch -c fix/invoice-rounding

# نفّذ التغيير
git add -p
git commit -m "تصحيح تقريب ضريبة الفاتورة"

git push -u origin fix/invoice-rounding

بعد دمج pull request:

git switch main
git pull --ff-only
git branch -d fix/invoice-rounding

لماذا هو شائع؟

  • عدد قليل من الفروع الدائمة.

  • ربط سهل بين التغيير والمراجعة والفحوص الآلية.

  • مناسب للنشر المتكرر.

  • بسيط بما يكفي للفرق الصغيرة والمتوسطة.

  • تدعم draft pull requests الملاحظات المبكرة.

ما الذي يتطلبه؟

GitHub Flow بسيط هيكليًا، لكنه يعتمد على الانضباط والأتمتة:

  • يجب أن يبقى الفرع الافتراضي قابلًا للإصدار أو الإصلاح السريع.

  • يجب ألا تبقى الفروع مفتوحة لفترات طويلة.

  • ينبغي أن تكون pull requests صغيرة بما يكفي لمراجعتها جيدًا.

  • يجب أن يوفر CI ملاحظات سريعة وموثوقة.

  • قد تحتاج الميزات غير المكتملة إلى feature flags.

  • يجب أن تكون عمليات النشر والتراجع موثوقة.

متى يكون مناسبًا؟

يناسب GitHub Flow خدمات الويب وواجهات API ومنتجات SaaS والتوثيق والتطبيقات التي يمكن نشرها بانتظام من فرع دمج رئيسي واحد.

GitHub Flow ليس خاصًا بـ GitHub فقط

يمكن تطبيق مفاهيم مسار العمل على GitLab أوBitbucket أوAzure DevOps أوأي خدمة استضافة أخرى. وقد يسمى كائن المراجعة الخاص بالمنصة pull request أوmerge request، لكن نموذج الفروع يبقى متشابهًا.

يشير الاسم إلى مسار العمل الذي نشرته GitHub، وليس إلى أمر Git مدمج في نظام التحكم بالإصدارات.

مسار العمل 4: استراتيجية فروع بسيطة بأسلوب GitLab

تؤكد إرشادات GitLab الحالية للفروع أن كثيرًا من الفرق يمكنها استخدام استراتيجية بسيطة:

  1. أنشئ فرع ميزة.

  2. افتح merge request.

  3. تحقق من التغيير وراجعه.

  4. ادمجه مباشرة في main.

يشبه هذا GitHub Flow من ناحية البنية.

توثق GitLab أيضًا استراتيجيات أكثر تعقيدًا للمنتجات التي تحافظ على إصدارات تاريخية، أو تخدم خطوط إصدارات مختلفة للعملاء، أو تملك متطلبات اعتماد ونشر.

صيغة فروع البيئات

تنشئ بعض الفرق فروعًا تقابل البيئات:

main
staging
production

تُنقل الشيفرة بين البيئات عن طريق الدمج عبر هذه الفروع.

قد يوفر ذلك مسارًا بصريًا واضحًا، لكنه يحمل مخاطر:

  • قد يبتعد فرع البيئة عما هو منشور فعليًا.

  • قد تتدفق hotfixes في الاتجاه الخطأ.

  • قد تصف merge commits آليات النشر بدل تطوير البرمجيات.

  • قد تحتوي عدة فروع على شيفرة مختلفة قليلًا.

تفضل أنظمة التسليم الحديثة غالبًا ترقية build artifacts غير القابلة للتغيير بين البيئات، بينما يبقى المصدر مرتبطًا بالتزام واحد. استخدم فروع البيئات فقط عندما يتطلب النموذج التشغيلي ذلك فعلًا.

صيغة فروع الإصدارات

قد يحتوي منتج تجري صيانته على:

main
release/3.0
release/2.5

يستمر التطوير الجديد على main، بينما تُنقل الإصلاحات المعتمدة إلى فروع الإصدارات المدعومة باستخدام backport.

يكون هذا مناسبًا عندما يجب دعم عدة إصدارات منشورة مستخدمة فعليًا.

مسار العمل 5: Git Flow

Git Flow نموذج فروع منظم صُمم حول إصدارات تحمل أرقام نسخ واضحة.

يستخدم تقليديًا فرعين طويلَي العمر:

  • main أو تاريخيًا master: سجل الإصدارات الجاهزة للإنتاج.

  • develop: فرع الدمج للإصدار التالي.

كما يستخدم فروع دعم مؤقتة:

  • feature/*: عمل جديد يُنشأ من develop.

  • release/*: استقرار إصدار يُنشأ من develop.

  • hotfix/*: إصلاحات إنتاج عاجلة تُنشأ من main.

                feature/a
               /         \
------develop--C-----------D------R------
     /                               \   \
main-A-----------------------------------M---H
                                      hotfix

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

Git Flow اتفاق وليس ميزة في Git

لا يعرف Git أن فرعًا اسمه develop مميز. Git Flow اتفاق داخل الفريق يُطبق باستخدام فروع وعمليات دمج وعلامات عادية.

يمكن لإضافات سطر الأوامر الاختيارية المسماة git-flow أتمتة خطوات إنشاء الفروع وإنهائها، لكن النموذج لا يتطلبها. يجب أن يفهم الفريق عمليات Git الأساسية بدل الاعتماد الأعمى على أوامر wrapper.

مسار الميزات في Git Flow

أنشئ فرع التطوير طويل العمر مرة واحدة:

git switch main
git switch -c develop
git push -u origin develop

أنشئ ميزة من develop:

git switch develop
git pull --ff-only
git switch -c feature/task-search

# نفّذ العمل وأنشئ الالتزام
git add -p
git commit -m "إضافة مطابقة الكلمات المفتاحية للمهام"

أنه الميزة:

git switch develop
git merge --no-ff feature/task-search
git branch -d feature/task-search

لا تُدمج الميزة عادة مباشرة داخل main.

مسار الإصدار في Git Flow

عندما يحتوي develop على الميزات المطلوبة للإصدار:

git switch develop
git switch -c release/2.0.0

ينبغي أن يركز فرع الإصدار على مهام الاستقرار مثل:

  • إصلاح الأخطاء.

  • تحديثات النسخة.

  • ملاحظات الإصدار.

  • تعديلات التغليف.

  • اختبارات التوافق النهائية.

ينبغي عادة تأجيل الميزات الكبيرة الجديدة إلى الإصدار التالي.

عندما يصبح جاهزًا:

git switch main
git merge --no-ff release/2.0.0
git tag -a v2.0.0 -m "إصدار النسخة 2.0.0"

git switch develop
git merge --no-ff release/2.0.0

git branch -d release/2.0.0

يجب أن تعود إصلاحات الإصدار إلى develop حتى لا تضيع في الإصدارات اللاحقة.

مسار Hotfix في Git Flow

يبدأ إصلاح الإنتاج العاجل من main:

git switch main
git switch -c hotfix/2.0.1

نفّذ الإصلاح واختبره:

git add -p
git commit -m "رفض استدعاءات الدفع المكررة"

ادمجه في سجل الإنتاج وضع عليه علامة:

git switch main
git merge --no-ff hotfix/2.0.1
git tag -a v2.0.1 -m "إصدار النسخة 2.0.1"

ثم ادمج الإصلاح في develop، أو في فرع إصدار نشط عندما تتطلب سياسة المشروع ذلك:

git switch develop
git merge --no-ff hotfix/2.0.1

git branch -d hotfix/2.0.1

مزايا Git Flow

  • فصل واضح بين الإنتاج وتطوير الإصدار التالي.

  • فروع مخصصة لاستقرار الإصدارات.

  • مسار hotfix واضح يبدأ من الإنتاج.

  • مفيد للمنتجات ذات النسخ الرسمية والإصدارات المجدولة.

  • يمكنه دعم البرامج الموزعة على عملاء يحدّثون في أوقات مختلفة.

  • يوفر مصطلحات مشتركة لأغراض الفروع.

تكاليف Git Flow

  • يجب إبقاء عدة فروع متزامنة.

  • قد تنتظر الميزات وقتًا أطول قبل وصولها إلى الإنتاج.

  • قد يخفي دمج develop طويل الأمد مخاطر الإصدار.

  • يجب دمج hotfixes وإصلاحات الإصدارات في عدة وجهات.

  • قد يصبح مخطط السجل معقدًا.

  • يصبح continuous delivery أصعب عندما لا يأتي الإنتاج مباشرة من خط الدمج الرئيسي.

  • قد تتبع الفرق المخطط آليًا حتى عندما لا يعود المنتج بحاجة إليه.

متى يبقى Git Flow مناسبًا؟

يمكن أن يناسب Git Flow المشاريع التي:

  • تنشر برامج تحمل أرقام نسخ واضحة.

  • تملك جداول إصدارات مخططة.

  • تحتاج إلى فترة استقرار.

  • تدعم عدة إصدارات يستخدمها العملاء.

  • لا تستطيع نشر كل تغيير مقبول فورًا.

  • تحتاج إلى تنسيق مخصص للإصلاحات العاجلة والإصدارات.

قد تشمل الأمثلة تطبيقات سطح المكتب، وإصدارات الهاتف المقيدة بمراجعة المتاجر، والمنتجات المؤسسية المثبتة، والبرامج الثابتة، والمكتبات ذات خطوط الإصدارات المدعومة.

متى يكون Git Flow ثقيلًا عادة؟

أوضح صاحب النموذج الأصلي لاحقًا أن تطبيقات الويب ذات التسليم المستمر تستفيد غالبًا من مسار أبسط مثل GitHub Flow. ولا ينبغي التعامل مع Git Flow بوصفه معيارًا عالميًا.

قد يكون غير ضروري عندما:

  • ينشر الفريق من main عدة مرات يوميًا.

  • يوجد إصدار إنتاج نشط واحد فقط.

  • يمكن إخفاء التغييرات باستخدام feature flags.

  • تكون الاختبارات الآلية والنشر ناضجة.

  • يكون fix-forward هو الاستراتيجية التشغيلية المعتادة.

  • يضيف فرع develop دائم تأخيرًا من دون حل قيد فعلي متعلق بالإصدار.

مسار العمل 6: Trunk-Based Development

ينظم trunk-based development العمل حول فرع دمج رئيسي واحد، يُسمى عادة main أوtrunk.

يعمل المطورون بإحدى طريقتين:

  • إنشاء الالتزامات مباشرة على trunk داخل فريق صغير جدًا وعالي الانضباط.

  • استخدام فروع ميزات قصيرة جدًا تُدمج بسرعة في trunk.

       a
      / \
A---B---C---D---E---F  main
          \ /
           b

تكون الفروع قصيرة عمدًا. والصفة المحددة هي التكامل المتكرر، لا الغياب الحرفي للفروع.

Trunk-Based Development لا يعني أن الجميع يدفع أي شيء إلى Main

يتطلب مسار trunk-based ناجح ضوابط هندسية قوية:

  • اختبارات آلية سريعة.

  • تغييرات صغيرة.

  • Continuous integration.

  • مزامنة متكررة.

  • مراجعة شيفرة لا تسبب تأخيرات طويلة.

  • Feature flags للعمل الظاهر للمستخدم وغير المكتمل.

  • Branch by abstraction للتغييرات البنيوية الكبيرة.

  • نشر ومراقبة موثوقان.

  • إصلاح سريع عندما يصبح trunk غير سليم.

العمل المباشر على trunk من دون هذه الممارسات ليس trunk-based development ناضجًا، بل تكامل غير مضبوط.

صيغة الفروع قصيرة العمر

مسار العمل الشائع والقابل للتوسع:

git switch main
git pull --ff-only
git switch -c change/add-search-index

# أكمل زيادة صغيرة
git add -p
git commit -m "إضافة فهرس البحث في المهام"

git push -u origin change/add-search-index

تشغّل pull request الفحوص وتحصل على مراجعة سريعة. وتُدمج خلال ساعات أو عدد قليل من الأيام، لا أسابيع.

تبدأ الزيادة التالية للميزة الكبيرة من trunk المحدث كتغيير صغير جديد.

Feature Flags في Trunk-Based Development

تفصل feature flag تكامل الشيفرة عن تفعيل الميزة.

مثال:

if (FeatureFlags::enabled('task_search_v2')) {
    return $newSearchService->search($query);
}

return $legacySearchService->search($query);

يمكن أن تدخل الوظيفة غير المكتملة إلى main مع بقائها معطلة للمستخدمين العاديين.

يمكن لرايات الميزات دعم:

  • التسليم التدريجي.

  • الاختبار الداخلي.

  • الإطلاق القائم على النسبة المئوية.

  • التفعيل الخاص بعملاء محددين.

  • التعطيل التشغيلي السريع.

تنشئ رايات الميزات أيضًا عمل صيانة. ويجب إزالة العلامات القديمة بعد اكتمال قرارات الإطلاق.

Branch by Abstraction

قد لا يتسع العمل المعماري الكبير داخل التزام صغير واحد. تسمح branch by abstraction بتعايش التنفيذ القديم والجديد خلف واجهة مستقرة.

العملية المبسطة:

  1. أدخل abstraction حول السلوك الحالي.

  2. انقل السلوك الحالي خلف abstraction.

  3. أضف التنفيذ الجديد تدريجيًا.

  4. اختر السلوك باستخدام configuration أوfeature flag.

  5. انقل callers والبيانات بأمان.

  6. أزل التنفيذ القديم وabstraction المؤقتة عندما يصبح ذلك مناسبًا.

يحافظ هذا على تكامل متكرر من دون الحاجة إلى فرع إعادة كتابة طويل العمر.

الإصدار في Trunk-Based Development

يوجد أسلوبان شائعان:

الإصدار مباشرة من Trunk

ينبغي أن يكون كل التزام مقبول على trunk مرشحًا محتملًا للإصدار. تختار أتمتة النشر التزامًا مختبرًا أو تنشره باستمرار.

إنشاء فرع إصدار في الوقت المناسب

يُنشأ فرع إصدار قرب موعد الإصدار:

git switch main
git switch -c release/3.2

يستمر التطوير الجديد على main. ويقبل فرع الإصدار فقط الإصلاحات الحرجة للإصدار، وغالبًا ما تُطوّر أولًا على trunk ثم تُنقل باستخدام backport.

يختلف ذلك عن استخدام فرع تطوير إصدار طويل العمر تتراكم فيه جميع الميزات لأشهر.

مزايا Trunk-Based Development

  • يحدث التكامل باستمرار بدل قرب النهاية.

  • تكون التعارضات أصغر عادة لأن التباعد محدود.

  • يوجد مصدر رئيسي واحد لحقيقة التطوير الحالية.

  • يدعم continuous delivery والملاحظات السريعة.

  • يمنع أحداث الدمج الكبيرة.

  • تكتشف الفرق التغييرات غير المتوافقة مبكرًا.

المخاطر والمتطلبات

  • قد تسمح الاختبارات الآلية الضعيفة بحدوث أعطال متكررة.

  • تحول المراجعات البطيئة الفروع القصيرة إلى فروع طويلة العمر.

  • تتطلب التغييرات الكبيرة feature flags أو تقنيات abstraction.

  • يجب على المطورين تقسيم العمل إلى زيادات صغيرة.

  • يجب التعامل مع trunk المعطّل فورًا.

  • قد ينتج عن الإدارة السيئة لرايات الميزات تعقيد خفي.

مسار العمل 7: Forking Workflow

يشيع Forking Workflow في المشاريع مفتوحة المصدر والمستودعات التي لا ينبغي منح المساهمين فيها صلاحية كتابة مباشرة.

يملك كل مساهم:

  • نسخة محلية.

  • Fork شخصيًا على الخادم.

  • اتصال remote بالمستودع الرسمي.

من القواعد الشائعة لتسمية remote:

  • origin: الـfork الخاص بالمساهم.

  • upstream: المستودع الرسمي.

الإعداد الأولي

git clone git@github.com:contributor/project.git
cd project

git remote add upstream git@github.com:organization/project.git
git remote -v

التحديث من المستودع الرسمي

git fetch upstream
git switch main
git merge --ff-only upstream/main
git push origin main

إنشاء مساهمة ونشرها

git switch -c fix/date-parser

# نفّذ التغييرات وأنشئ الالتزام
git add -p
git commit -m "رفض تواريخ التقويم غير الصالحة"

git push -u origin fix/date-parser

يفتح المساهم pull request من فرع الـfork إلى المستودع الرسمي.

المزايا

  • لا يحتاج المساهمون الخارجيون إلى صلاحية كتابة على المستودع الرسمي.

  • يتحكم المشرفون في الدمج.

  • يستطيع المساهمون نشر فروعهم واختبارها.

  • يتوسع جيدًا مع المجتمعات المفتوحة.

التكاليف

  • يجب على المساهمين إدارة اثنين من remotes.

  • قد تصبح فروع الـfork قديمة.

  • قد تُقيّد أسرار CI والصلاحيات في builds القادمة من forks غير موثوقة.

  • يحتاج المشرفون إلى سياسات مساهمة ومراجعة واضحة.

طرق الدمج جزء من مسار العمل

يمكن دمج pull request بعدة طرق، وتغير الطريقة المختارة سجل المستودع.

Merge Commit

git switch main
git merge --no-ff feature/task-search

خصائصه:

  • يحافظ على الالتزامات الفردية لفرع الميزة.

  • ينشئ التزام دمج صريحًا.

  • يحافظ على بنية الفروع.

  • قد ينشئ سجلًا بصريًا معقدًا عندما تكون الفروع كثيرة.

Squash Merge

تجمع منصة الاستضافة أو مسار العمل المحلي فرق الميزة في التزام جديد واحد على الفرع الهدف.

A---B---S  main
     \
      C---D---E  feature

خصائصه:

  • ينتج التزامًا واحدًا لكل pull request.

  • يسمح بوجود التزامات غير مرتبة داخل الفرع من دون حفظها في main.

  • يزيل علاقة الأب الأصلية بين سجل الهدف والتزامات الميزة.

  • قد يجعل التراجع الجزئي أسهل على مستوى pull request.

  • يفقد التفاصيل الدقيقة لسجل فرع الميزة من المسار الرئيسي.

Rebase and Merge

تُعاد تطبيق التزامات الميزة على الفرع الهدف وتُضاف من دون merge commit:

A---B---C'---D'---E'  main

خصائصه:

  • ينشئ سجلًا خطيًا.

  • يحافظ على الالتزامات المنطقية الفردية عندما تكون نظيفة.

  • ينشئ معرّفات التزامات بديلة.

  • يتطلب الحذر عندما يكون سجل الفرع الأصلي قد جرى مشاركته.

  • لا ينشئ merge commit صريحًا.

كيفية اختيار طريقة الدمج

الطريقةالأنسب عندماالمقايضة الرئيسية
Merge commitتكون بنية الفروع وأحداث الدمج مهمةرسم أكثر تعقيدًا
Squash mergeيجب أن يصبح التغيير المراجع التزامًا واحدًا على المسار الرئيسيتُحذف تفاصيل التزامات الميزة من السجل الرئيسي
Rebase and mergeتكون التزامات الميزة نظيفة ويكون السجل الخطي مطلوبًاتُعاد كتابة الالتزامات ولا يبقى حد دمج

ينبغي للفريق اختيار طريقة واحدة أو مجموعة صغيرة من الطرق المسموح بها، وتوثيق وقت استخدام كل منها. الدمج غير المتسق يجعل السجل أصعب في التفسير.

Pull Requests طبقة تعاون وليست كائنًا في Git

يفهم Git الالتزامات والفروع والعلامات وعمليات الدمج وremotes. أما pull request أوmerge request فتقدمه منصة الاستضافة.

وهي تضيف:

  • النقاش.

  • التعليقات داخل السطر.

  • حالة المراجعة.

  • ملخصات الفحوص الآلية.

  • Issues مرتبطة.

  • سجلات الموافقة.

  • ضوابط الدمج.

  • Deployment previews.

قد يحتوي سجل Git النهائي على merge commit أوsquash commit أوالتزامات أُعيد تطبيقها بحسب طريقة الدمج المختارة.

Draft Pull Requests والمراجعة المبكرة

يمكن لـdraft pull request إظهار العمل قبل أن يصبح جاهزًا للدمج.

يفيد ذلك عندما:

  • يريد المطور ملاحظات معمارية مبكرة.

  • يؤثر التغيير في عدة فرق.

  • يجب أن يعمل CI قبل اكتمال التنفيذ.

  • تكون المناقشة الظاهرة أفضل من العمل الخاص.

  • يجب أن يبقى الفرع قصير العمر لكنه يحتاج إلى تعاون.

لا ينبغي أن تتحول draft إلى عذر لإبقاء الفرع مفتوحًا إلى أجل غير محدد. قسّم العمل الكبير إلى زيادات مستقلة قابلة للدمج.

حماية الفروع والقواعد

يصبح مسار العمل المكتوب موثوقًا عندما تفرض إعدادات المستودع قواعده الأساسية.

تشمل الحمايات الشائعة:

  • منع الدفع المباشر إلى main.

  • اشتراط pull request أوmerge request.

  • اشتراط موافقة واحدة أو أكثر.

  • إلغاء الموافقات بعد إضافة التزامات جديدة مهمة.

  • اشتراط حل المحادثات.

  • اشتراط فحوص حالة محددة.

  • اشتراط تحديث الفرع مع الهدف.

  • اشتراط التزامات أوعلامات موقعة عند الحاجة.

  • تقييد من يمكنه الدمج أو إنشاء الإصدارات.

  • منع حذف الفروع أوforce pushes.

لا تفعّل كل قاعدة متاحة تلقائيًا. فكل فحص إلزامي يصبح جزءًا من مسار التسليم ويجب أن يبقى موثوقًا.

CI/CD بوصفه نظام الملاحظات لمسار العمل

غالبًا ما ينتج مسار العمل من دون تحقق سريع فترات انتظار طويلة وعمليات دمج كبيرة وعالية المخاطر.

قد تشغّل pipeline الخاصة بـpull request:

  1. تثبيت dependencies.

  2. فحوص formatting وlint.

  3. التحليل الثابت.

  4. Unit tests.

  5. Integration tests.

  6. فحص الأمان والأسرار.

  7. التحقق من database migrations.

  8. بناء التطبيق.

  9. بناء container.

  10. نشر بيئة preview.

وقد تقوم pipeline بعد الدمج بما يلي:

  • بناء artifact غير قابل للتغيير.

  • النشر إلى staging.

  • تشغيل smoke tests.

  • ترقية artifact نفسه إلى production.

  • إنشاء سجل إصدار.

  • تسجيل الالتزام والعلامة اللذين جرى نشرهما.

حافظ على Main Branch في حالة خضراء

يعني main branch الأخضر أن أحدث حالة مدمجة اجتازت التحقق المطلوب.

عندما يصبح أحمر:

  • أوقف إضافة التغييرات غير المرتبطة عند الحاجة.

  • حدد عملية الدمج المسؤولة بسرعة.

  • نفّذ revert أوfix-forward وفق سياسة الفريق.

  • استعد سلامة الفرع قبل متابعة التسليم المعتاد.

  • حسّن الاختبار أوالتحقق المفقود الذي سمح بمرور الخطأ.

الفرع الرئيسي المعطل الذي يبقى معطلًا أيامًا يدمر الثقة في مسار العمل.

فروع الإصدارات: طويلة العمر مقابل المنشأة في الوقت المناسب

يمكن أن يصف الاسم release/* استراتيجيتين مختلفتين جدًا.

فرع إصدار مدعوم طويل العمر

main
release/3.x
release/2.x

توجد هذه الفروع لأن عدة إصدارات منشورة ما تزال مدعومة.

فرع استقرار مؤقت

release/4.0.0

يوجد هذا الفرع فقط أثناء إنهاء إصدار واحد، ثم يُدمج أو يُنهى.

فرع منشأ من Trunk في الوقت المناسب

يُقتطع الفرع قرب موعد الإصدار، ويتلقى فقط التغييرات الحرجة للإصدار، ويُحذف بعد انتهاء التزامات الدعم.

ينبغي لوثيقة مسار العمل تحديد المعنى المقصود.

Hotfixes وBackports

يصلح hotfix الإنتاج النشط. أما backport فيطبق إصلاحًا على خط إصدار أقدم ما يزال مدعومًا.

من المبادئ الآمنة تطوير الإصلاح في أقدم خط شيفرة ذي صلة عند الحاجة، ثم نقله نحو الخطوط الأحدث، أو تطويره على trunk ونقله إلى الخلف باستخدام cherry-pick عندما تدعم سياسة المشروع ذلك.

مثال على backport:

# الإصلاح موجود على main بالمعرّف abc1234
git switch release/2.5
git cherry-pick -x abc1234

يسجل الخيار -x معرّف الالتزام الأصلي داخل رسالة الالتزام الجديد عندما تنتهي cherry-pick من دون تعارضات، ما يساعد على تتبع backport.

بعد تنفيذ backport:

  • شغّل اختبارات الإصدار الأقدم.

  • تحقق من التوافق مع dependencies والمخططات الأقدم.

  • أنشئ علامة patch release المناسبة.

  • تأكد من وجود الإصلاح في خطوط الصيانة الأحدث أيضًا.

Feature Flags مقابل Feature Branches

يعزل feature branch سجل المصدر، بينما تتحكم feature flag في السلوك وقت التشغيل.

Feature BranchFeature Flag
يفصل الالتزامات قبل الدمجيفصل النشر عن التفعيل
قد يراكم تباعد الدمجقد يراكم تعقيد وقت التشغيل
مفيد للمراجعة والعزلمفيد للإطلاق التدريجي والعمل المخفي
يُزال بعد الدمجينبغي إزالته بعد قرارات الإطلاق

تستخدم الفرق الناضجة غالبًا الاثنين: فرعًا قصير العمر للمراجعة، وراية لإبقاء الوظيفة غير المكتملة معطلة بعد الدمج.

تطبيق يدوي: مسار خفيف قائم على Pull Request

1. إعداد Main

git switch main
git fetch origin
git merge --ff-only origin/main
git status

2. إنشاء فرع مركز

git switch -c feature/task-search

3. إنشاء التزامات منطقية

git add src/SearchService.php
git commit -m "إضافة مطابقة الكلمات المفتاحية للمهام"

git add tests/SearchServiceTest.php
git commit -m "اختبار مطابقة الكلمات المفتاحية للمهام"

4. مراجعة الفرع

git log --oneline main..HEAD
git diff --stat main...HEAD
git diff main...HEAD

5. النشر

git push -u origin feature/task-search

6. فحوص Pull Request

  • تنجح الاختبارات الآلية.

  • يحتوي الفرق على ميزة منطقية واحدة.

  • لا توجد أسرار أو ملفات مولدة.

  • جرت معالجة تعليقات المراجعة.

  • الفرع محدث عندما تتطلب السياسة ذلك.

7. الدمج والتنظيف

git switch main
git pull --ff-only
git branch -d feature/task-search

تطبيق يدوي: إصدار Git Flow

الفروع طويلة العمر الأولية

A---B---C  main
         \
          D---E---F  develop

إنشاء فرع الإصدار

git switch develop
git switch -c release/2.0.0

الاستقرار

git add CHANGELOG.md
git commit -m "تحضير ملاحظات الإصدار 2.0.0"

git add src/Version.php
git commit -m "ضبط نسخة التطبيق على 2.0.0"

الدمج في Main وإضافة علامة

git switch main
git merge --no-ff release/2.0.0
git tag -a v2.0.0 -m "إصدار النسخة 2.0.0"

إعادة إصلاحات الإصدار إلى Develop

git switch develop
git merge --no-ff release/2.0.0
git branch -d release/2.0.0

التحقق

git log --oneline --graph --decorate --all
git show v2.0.0

تطبيق يدوي: زيادة Trunk-Based خلف راية

1. إنشاء فرع قصير العمر

git switch main
git pull --ff-only
git switch -c change/search-routing

2. إضافة مسار راية معطلة

if (FeatureFlags::enabled('new_task_search')) {
    return $newSearch->execute($query);
}

return $oldSearch->execute($query);

3. تسجيل زيادة صغيرة وآمنة

git add -p
git commit -m "توجيه بحث المهام من خلال feature flag"

4. التحقق والدمج بسرعة

git diff main...HEAD
git push -u origin change/search-routing

بعد المراجعة وCI، ادمج الفرع. يبقى المسار الجديد معطلًا.

5. المتابعة عبر فروع صغيرة جديدة

  • أضف تنفيذ البحث الجديد.

  • أضف مقاييس المقارنة.

  • فعّله للمستخدمين الداخليين.

  • أطلقه تدريجيًا.

  • أزل التنفيذ القديم.

  • أزل الراية.

تصل الميزة الكبيرة إلى الإنتاج عبر عدة زيادات آمنة ومدمجة بدل فرع واحد طويل العمر.

مقارنة مسارات العمل

مسار العملالفروع طويلة العمرتكرار الدمجأسلوب الإصدارالاستخدام المعتاد
Centralizedفرع واحد عادةمباشر ومتكررخاص بالمشروعمطور فردي أو فرق صغيرة جدًا وموثوقة
Feature Branchعادة mainعند اكتمال كل فرعمرنالتعاون العام داخل الفرق
GitHub FlowMainPull requests متكررةنشر متكرر من mainالويب وSaaS وواجهات API والتوثيق
Git FlowMain وdevelopمراحل الميزات والإصداراتإصدارات مجدولة تحمل أرقام نسخالمنتجات ذات دورات الإصدار الرسمية
Trunk-BasedMain/trunkمتكرر جدًامن trunk أوفرع إصدار منشأ في الوقت المناسبContinuous integration وdelivery
Forkingيعتمد على مشروع upstreamعبر pull requests خارجيةتحت تحكم المشرفينالمصدر المفتوح والمساهمون محدودو الصلاحية

كيفية اختيار مسار العمل

اختر نموذج Main مع فروع ميزات خفيفة عندما:

  • ينشر الفريق بانتظام.

  • يوجد إصدار إنتاج حالي واحد.

  • توفر pull requests وCI تحكمًا كافيًا.

  • لن يضيف فرع دمج دائم قيمة كبيرة.

اختر Git Flow أو نموذجًا موجهًا للإصدارات عندما:

  • تكون الإصدارات مرقمة ومجدولة بوضوح.

  • يكون فرع استقرار رسمي ضروريًا.

  • تحتاج عدة إصدارات إلى الصيانة.

  • يجب أن تتبع hotfixes عملية إصدار محددة.

  • لا يمكن النشر بعد كل تغيير مقبول.

اختر Trunk-Based Development عندما:

  • يكون التحقق الآلي سريعًا وموثوقًا.

  • يستطيع الفريق تقسيم العمل إلى زيادات صغيرة.

  • يكون الدمج والنشر متكررين.

  • تتوفر feature flags وتقنيات branch by abstraction.

  • يتعامل الفريق فورًا مع trunk المعطل.

اختر Forking Workflow عندما:

  • لا ينبغي منح المساهمين صلاحية كتابة.

  • يكون المشروع عامًا أو يقبل مساهمات خارجية.

  • يحتاج المشرفون إلى التحكم في دمج المستودع الرسمي.

  • تدعم منصة الاستضافة pull requests بين forks.

مصفوفة قرار عملية

حالة المشروعالاتجاه المرجح
النشر عدة مرات يوميًاGitHub Flow أوtrunk-based development
فريق صغير واحد وCI قوي ومراجعات سريعةفروع قصيرة العمر حول main
إصدارات حزم شهريةفروع إصدار أوGit Flow
دعم عدة إصدارات للعملاءفروع إصدار قيد الصيانة
قاعدة كبيرة من مساهمي المصدر المفتوحForking workflow مع مراجعة المشرفين
اختبارات آلية ضعيفة أو بطيئةتحسين التحقق قبل زيادة سرعة الدمج
ميزات يستغرق بناؤها أشهرًاتقسيم الزيادات وfeature flags وbranch by abstraction
متطلبات موافقة وتدقيق رسميةفروع محمية مع مراجعات وفحوص إلزامية

أنماط مسارات العمل السيئة

فروع الميزات طويلة العمر

تؤجل الدمج وتنشئ عمليات دمج كبيرة وعالية المخاطر.

فرع Develop دائم من دون حاجة للإصدار

إذا كان كل تغيير مقبول سيُنشر في النهاية من main، فقد يضيف فرع دمج إضافي مجرد تأخير في المزامنة.

فروع بيئات لا تطابق عمليات النشر

اسم الفرع ليس دليلًا على ما يعمل في البيئة. سجّل الالتزامات والملفات المنشورة بوضوح.

Pull Requests ضخمة

تنخفض جودة المراجعة مع زيادة الحجم والتعقيد.

فروع تحمل أسماء أشخاص

أسماء مثل adnan-work تصف الملكية بدل الغرض وقد تجمع تغييرات غير مرتبطة.

تنفيذ Rebase عشوائي على الفروع المشتركة

إعادة كتابة الالتزامات المنشورة تربك المتعاونين والمراجع الآلية.

استخدام Cherry-Pick كطريقة الدمج الافتراضية

ينسخ cherry-pick تغييرات فردية لكنه لا يمثل علاقة دمج على مستوى الفرع. استخدمه عمدًا في backports والالتزامات المختارة.

حماية Main بفحوص غير موثوقة

قد يمنع اختبار إلزامي متذبذب جميع المطورين ويعلّم الفريق عدم الثقة بالأتمتة.

الاحتفاظ بالفروع الميتة إلى الأبد

تجعل الفروع القديمة حالة المستودع أصعب في الفهم.

اختيار مسار عمل لأن الأداة توفر زرًا له

ينبغي أن تقود قيود إصدار المنتج وصيانته العملية، لا قائمة ميزات منصة الاستضافة.

أفضل الممارسات لمسارات العمل

  • استخدم أقل عدد من الفروع الدائمة التي تحل المشكلة الفعلية.

  • حافظ على قصر عمر الفروع متى أمكن.

  • افصل التغييرات غير المرتبطة.

  • راجع فرق الفرع، لا الالتزامات الفردية فقط.

  • اشترط فحوصًا آلية سريعة وذات صلة.

  • حافظ على صحة الفرع الافتراضي.

  • احذف الفروع المؤقتة المكتملة.

  • استخدم علامات الإصدارات لتحديد النسخ المسلّمة.

  • وثق مسارات hotfix وbackport.

  • حدد طرق الدمج المسموح بها.

  • استخدم feature flags للوظائف المدمجة غير المكتملة.

  • أزل feature flags القديمة.

  • سجّل الالتزام والـartifact اللذين وصلا إلى كل بيئة.

  • أعد تقييم مسار العمل عندما تتغير احتياجات التسليم.

وثّق مسار العمل داخل المستودع

ينبغي لوثيقة مسار عمل عملية الإجابة عن:

  • ما الفرع الافتراضي؟

  • هل يستطيع أحد الدفع إليه مباشرة؟

  • من أين يجب أن تبدأ فروع الميزات؟

  • كيف تُسمى الفروع؟

  • ما الحجم المناسب لـpull requests؟

  • ما الفحوص والموافقات المطلوبة؟

  • ما طرق الدمج المسموح بها؟

  • من يمكنه إنشاء علامات الإصدار؟

  • كيف تُنشأ الإصدارات؟

  • كيف تُعالج hotfixes في الإنتاج؟

  • كيف تُنقل الإصلاحات إلى الإصدارات الأقدم؟

  • متى ينبغي حذف الفروع؟

  • ماذا يحدث عندما يتعطل الفرع الرئيسي؟

احفظ السياسة في ملف ظاهر مثل:

CONTRIBUTING.md
docs/development-workflow.md
docs/release-process.md

ينبغي للوثيقة شرح القرارات، لا مجرد سرد الأوامر.

مثال على سياسة فريق خفيفة

الفرع الافتراضي: main

أسماء الفروع:
- feature/<وصف-قصير>
- fix/<وصف-قصير>
- docs/<وصف-قصير>

القواعد:
1. تُمنع عمليات الدفع المباشر إلى main.
2. يستخدم كل تغيير pull request.
3. تُطلب موافقة واحدة على الأقل.
4. يجب أن تنجح unit tests والتحليل الثابت وفحوص build.
5. ينبغي أن تحتوي pull requests على تغيير منطقي واحد.
6. يُستخدم squash merge لفروع الميزات العادية.
7. تكون علامات الإصدار annotated وتُنشئها release pipeline.
8. تُحذف الفروع المكتملة تلقائيًا.
9. يُصلح main المعطل أو يُعاد عنه فورًا.

مثال على سياسة فريق موجهة للإصدارات

الفروع طويلة العمر:
- main: إصدارات الإنتاج المنشورة
- develop: الإصدار المخطط التالي

الفروع الداعمة:
- feature/* من develop
- release/* من develop
- hotfix/* من main

القواعد:
1. تُدمج فروع الميزات في develop.
2. تقبل فروع الإصدار تغييرات الاستقرار فقط.
3. تُدمج الإصدارات المكتملة في main وdevelop.
4. تحصل التزامات الإصدار على main على علامات نسخة annotated.
5. تُدمج hotfixes في main وdevelop.
6. تتلقى فروع الإصدارات المدعومة backports معتمدة.
7. لا يُسمح بـforce push على الفروع المحمية.

الانتقال من Git Flow إلى مسار أبسط

يمكن لفريق لم يعد يحتاج إلى فروع إصدار رسمية أن يبسّط العملية تدريجيًا.

  1. حدد سبب وجود develop اليوم.

  2. تأكد من أن main يمكن أن يصبح فرع الدمج الرئيسي.

  3. حسّن CI وأتمتة النشر.

  4. قصّر عمر فروع الميزات.

  5. انقل تحضير الإصدارات إلى الأتمتة أو فروع تُنشأ في الوقت المناسب.

  6. ادمج سجل develop المطلوب في main.

  7. حدّث حماية الفروع ومشغلات pipeline.

  8. حدّث التوثيق وأدوات المطورين.

  9. أنه استخدام develop فقط بعد حصر العمل النشط.

لا تحذف فرعًا طويل العمر قبل تحديد الالتزامات الفريدة وpull requests المفتوحة واعتماديات pipeline.

الانتقال نحو Trunk-Based Development

Trunk-based development قدرة هندسية، وليس مجرد تغيير اسم فرع.

قد تتضمن عملية انتقال واقعية:

  1. تقليل حجم pull requests.

  2. تحسين موثوقية الاختبارات ووقت تنفيذها.

  3. أتمتة formatting والفحوص الثابتة.

  4. إدخال feature flags.

  5. تعليم branch by abstraction.

  6. تحديد الحد الأقصى المتوقع لعمر الفرع.

  7. توفير مسؤولية مراجعة سريعة.

  8. قياس مدة انتظار التغييرات قبل الدمج.

  9. تعزيز observability وإجراءات rollback أوfix-forward للنشر.

  10. إزالة الفروع الدائمة غير الضرورية.

مقاييس تكشف مشكلات مسار العمل

تشمل المؤشرات المفيدة:

  • الوسيط لعمر الفرع.

  • مدة انتظار pull request.

  • زمن الاستجابة للمراجعة.

  • حجم pull request.

  • تكرار تعارضات الدمج.

  • مدة CI ومعدل فشله.

  • مدة بقاء الفرع الافتراضي معطلًا.

  • تكرار النشر.

  • المدة من أول التزام حتى الإنتاج.

  • معدلات فشل التغييرات والاستعادة.

  • عدد الفروع القديمة وأعمارها.

  • عدد feature flags القديمة وأعمارها.

ينبغي للمقاييس توجيه التحسين، لا أن تتحول إلى أهداف يتلاعب بها المطورون.

قائمة التحقق لمسار عمل Git

قبل اعتماد مسار عمل:

  • وتيرة الإصدار مفهومة.

  • سياسة الإصدارات المدعومة موثقة.

  • الحالة المتوقعة للفرع الافتراضي محددة.

  • للفروع الدائمة المطلوبة غرض حقيقي.

  • نموذج المراجعة والموافقة واضح.

  • CI pipeline موثوقة بما يكفي لفرض الفحوص المطلوبة.

  • طريقة الدمج مختارة عمدًا.

  • عملية hotfix وbackport محددة.

  • علامات الإصدار ومصدر artifact محددان.

  • تطابق حماية الفروع السياسة المكتوبة.

أثناء العمل اليومي:

  • ابدأ من base صحيحة ومحدثة.

  • أنشئ فرعًا واحدًا لكل تغيير منطقي.

  • حافظ على وضوح الالتزامات.

  • ادفع بانتظام عند الحاجة إلى التعاون أو النسخ الاحتياطي.

  • افتح المراجعة مبكرًا للعمل عالي المخاطر.

  • حافظ على قصر عمر الفرع.

  • استجب بسرعة لملاحظات CI والمراجعة.

  • احذف الفرع بعد الدمج.

الأسئلة الشائعة

هل Git Flow مدمج داخل Git؟

لا. إنه اتفاق لتنظيم الفروع يُطبق باستخدام أوامر Git عادية. ويمكن لإضافات اختيارية أتمتة بعض أجزائه.

هل GitHub Flow خاص بـ GitHub فقط؟

لا. يمكن استخدام نموذج الفروع قصيرة العمر والمراجعة على منصات استضافة أخرى.

هل يمنع Trunk-Based Development استخدام الفروع؟

لا. تستخدم الفرق الأكبر عادة فروعًا قصيرة جدًا للمراجعة والتحقق الآلي.

هل يجب أن يملك كل مشروع فرع Develop؟

لا. أضفه فقط عندما يمثل مرحلة دمج أو إصدار حقيقية لا يستطيع الفرع الرئيسي خدمتها.

ما أفضل مسار عمل لتطبيقات Laravel أو الويب؟

في تطبيق ويب يُنشر بانتظام، يكون فرع main محمي مع فروع ميزات قصيرة العمر وpull requests وCI وfeature flags أبسط غالبًا من Git Flow الكامل. وتظل قيود النشر والدعم في المشروع هي التي تحدد القرار النهائي.

ما الفرق بين GitHub Flow وTrunk-Based Development؟

قد يبدوان متشابهين. يمكن لكليهما استخدام فرع رئيسي واحد وفروع قصيرة العمر. يركز trunk-based development على الدمج المتكرر جدًا والحد الأدنى لعمر الفرع وتقنيات مثل feature flags. بينما يركز GitHub Flow على تسلسل التعاون باستخدام pull requests والنشر من الفرع الافتراضي.

متى ينبغي استخدام Git Flow؟

استخدمه عندما تبرر الإصدارات الرسمية المرقمة وفروع الاستقرار ومسارات hotfix في الإنتاج ودعم الإصدارات المنشورة بنية الفروع الإضافية.

هل يجب أن يكون Main قابلًا للنشر دائمًا؟

يعتمد ذلك على مسار العمل، لكن GitHub Flow ونماذج trunk-based تعمل عادة بأفضل صورة عندما يكون main قابلًا للإصدار أو يمكن استعادته بسرعة.

هل ينبغي تنفيذ Squash لكل Pull Request؟

ليس تلقائيًا. يفيد squash عندما يجب أن تصبح pull request التزامًا منطقيًا واحدًا في السجل الرئيسي. حافظ على الالتزامات الفردية عندما تحمل سجلًا مستقلًا ذا قيمة.

هل ينبغي للمطورين تنفيذ Rebase قبل فتح Pull Request؟

فقط عندما تتطلب سياسة السجل في الفريق ذلك ويكون من الآمن إعادة كتابة الفرع. لا تنفذ rebase عشوائيًا على عمل مشترك.

هل فروع الإصدارات غير متوافقة مع Trunk-Based Development؟

لا. يمكن اقتطاع فرع إصدار في الوقت المناسب من trunk عند الحاجة. والفرق الأساسي أن تطوير الميزات يستمر عبر trunk بدل تراكمه على فروع إصدار طويلة العمر.

كم ينبغي أن يعيش فرع الميزة؟

لأقصر مدة عملية. قد يتحمل مسار مراجعة خفيف بضعة أيام، بينما تستهدف فرق trunk-based ساعات أو فترات قصيرة جدًا. الفرع الذي يستمر أسابيع علامة على ضرورة تقسيم العمل.

هل يمكن لـCI أن يحل محل مراجعة الشيفرة؟

لا. تتحقق الأتمتة من خصائص محددة. أما المراجعة البشرية فتقيّم التصميم والهدف وقابلية الصيانة وسلوك المنتج والمخاطر التي لا تعبر عنها الاختبارات بالكامل.

هل يمكن لمراجعة الشيفرة أن تحل محل CI؟

لا. البشر ليسوا بديلًا جيدًا للتحقق الآلي القابل للتكرار.

كيف ينبغي معالجة إصلاح إنتاج عاجل؟

أنشئ الإصلاح من مصدر حقيقة الإنتاج، وتحقق منه، وأصدره، وتأكد من وصول التصحيح إلى كل خطوط التطوير أو الإصدارات النشطة الأحدث.

الخلاصة

مسار عمل Git اتفاق حول كيفية تحول التغييرات إلى برمجيات موثوقة. أسماء الفروع والمخططات ليست سوى البنية الظاهرة. ويشمل مسار العمل الحقيقي أيضًا المراجعات والاختبارات الآلية وطرق الدمج وحماية الفروع وتحديد الإصدارات والنشر والصيانة.

بالنسبة إلى كثير من الفرق الحديثة، يكون فرع main محمي مع فروع صغيرة قصيرة العمر وpull requests أفضل نقطة بداية. يعبّر GitHub Flow عن هذا النموذج بوضوح. ويأخذ trunk-based development الدمج المتكرر إلى مستوى أبعد، ويعتمد على أتمتة قوية وزيادات صغيرة وfeature flags ومراجعة سريعة.

يبقى Git Flow مفيدًا عندما يملك المنتج إصدارات رسمية مرقمة وفترات استقرار وhotfixes للإنتاج وعدة إصدارات مستخدمة فعليًا. وينبغي لفروعه الإضافية حل هذه القيود الحقيقية بدل وجودها لمجرد أن النموذج مألوف.

يعالج Forking Workflow مشكلة مختلفة: قبول المساهمات من دون منح صلاحية كتابة إلى المستودع الرسمي.

القاعدة الأهم هي تجنب التعقيد غير المقصود. ابدأ بأبسط مسار عمل يحمي الفرع الافتراضي ويدعم المراجعة. أضف فروع الإصدارات أو مسارات hotfix أو طبقات الموافقة أو الإصدارات قيد الصيانة فقط عندما يتطلب المنتج ذلك. وأعد تقييم العملية مع تغير قدرات التسليم واحتياجات العمل.

ستركز المقالة التالية على أفضل ممارسات Git للالتزامات النظيفة والتعاون داخل الفرق، وستجمع بين تسمية الفروع وتصميم الالتزامات وجودة المراجعة والأمان وصيانة المستودع والإدارة الآمنة للسجل.

المراجع الرسمية ومواد إضافية للقراءة