Git وتدفقات العمل التعاونية

مقارنة استراتيجيات التفريع

18 دقيقة الدرس 5 من 28

مقارنة استراتيجيات التفريع

يُعدّ اختيار استراتيجية التفريع من أعلى القرارات تأثيرًا على الفريق الهندسي. اختر الاستراتيجية الصحيحة وستصبح الإصدارات روتينًا اعتياديًا. اختر الخاطئة وستمضي فترات بعد الظهر في حلّ تعارضات الدمج، والأمسيات في تعقّب الانحدارات، وعطل نهاية الأسبوع في إطفاء حرائق الإصدارات المعطوبة. يرسم هذا الدرس الاستراتيجيات الثلاث السائدة — Git Flow وGitHub Flow والتطوير المُبنى على الجذع (Trunk-Based Development) — ويشرح المقايضات الهندسية لكل منها، مع توضيح ما تستخدمه الشركات الكبرى فعليًا في الإنتاج.

Git Flow: التطوير المتوازي المنظّم

قدّم Vincent Driessen نموذج Git Flow عام 2010، وهو يُحدّد مجموعة صارمة من الفروع الدائمة والمؤقتة. صُمّم في الأصل للبرمجيات التي تمتلك دورات إصدار واضحة — كمكتبات ذات إصدارات رقمية، أو تطبيقات الهاتف المحمول التي تُشحن عبر متاجر التطبيقات، أو برمجيات المؤسسات ذات الإصدارات الفصلية.

الفروع الدائمة: main (أو master) يعكس دائمًا بيئة الإنتاج. develop يجمع المميزات المكتملة قبل الإصدار.

الفروع المساندة (مؤقتة):

  • feature/* — يتفرع من develop ويندمج فيه.
  • release/* — يتفرع من develop عند اكتمال المميزات للإصدار؛ لا يقبل إلا إصلاحات الأخطاء؛ يندمج في main (مع وسم) وdevelop معًا.
  • hotfix/* — يتفرع مباشرةً من main؛ يندمج في main وdevelop معًا.
# تهيئة المستودع بنموذج Git Flow (يتطلب أداة git-flow) git flow init -d # قبول الإعدادات الافتراضية # بدء ميزة جديدة git flow feature start user-auth # إنهاؤها — الدمج في develop وحذف الفرع git flow feature finish user-auth # قطع إصدار git flow release start 2.4.0 # ... إصلاح أخطاء الإصدار، رفع رقم الإصدار ... git flow release finish 2.4.0 # يدمج في main + develop ويضع وسمًا على main # إصلاح طارئ على الإنتاج git flow hotfix start fix-payment-crash git flow hotfix finish fix-payment-crash
التكلفة الخفية لـ Git Flow: تتراكم التباينات على الفروع الدائمة develop وrelease. حين يُدمج release/2.4.0 أخيرًا، يكون develop قد تقدّم كثيرًا — والدمج العكسي إلى develop مؤلم بشكل موثّق. الفرق التي تبنّت Git Flow عام 2012 ولم تُراجعه منذ ذلك تقضي 20-30% من وقتها الهندسي في إدارة التعارضات. حتى Driessen نفسه أضاف ملاحظة في منشوره الأصلي يوصي فيها بالتطوير على الجذع للفرق التي تُطبّق التسليم المستمر.

GitHub Flow: البساطة للتسليم المستمر

يُختزل GitHub Flow في قاعدة واحدة: main قابل للنشر دائمًا. كل تغيير — ميزة أو إصلاح أو إعادة هيكلة — يعيش في فرع قصير الأمد يُفتح كطلب سحب (Pull Request)، يُراجع، ثم يندمج مباشرةً في main. يُنشر التطبيق فور الدمج أو خلاله عبر CI/CD.

# سير عمل GitHub Flow git switch -c feature/add-oauth main # ... عمل وإيداع ... git push origin feature/add-oauth # فتح PR عبر واجهة CLI gh pr create --base main --title "Add OAuth login" --body "Closes #412" # بعد الموافقة واجتياز CI، الدمج والنشر gh pr merge --squash --delete-branch # يُنشر main فورًا عبر خط CI/CD

يعمل GitHub Flow بكفاءة عالية لمنتجات SaaS التي تشحن عدة مرات في اليوم. طلب السحب هو وحدة العمل: يحمل الفرق والنقاش ونتائج CI وبوابة النشر في مكان واحد.

أين يُخفق GitHub Flow: لا يوفر آلية مدمجة لإدارة إصدارات متعددة متزامنة. إن احتجت للحفاظ على v2 وv3 في وقت واحد (شائع مع APIs أو SDKs الهاتفية)، فستكون بمفردك. غالبًا ما ترتجل الفرق فروع release/v2 دائمة، فتخترع فعليًا جزءًا من Git Flow فوق GitHub Flow.

التطوير على الجذع: ما تستخدمه الفرق عالية السرعة فعلًا

التطوير على الجذع هو الاستراتيجية خلف مستودع Google الموحّد (مليار سطر من الكود، فرع واحد)، وأدوات Meta الداخلية، وغالبية المنظمات الرائدة في التسليم المستمر. القاعدة أبسط من GitHub Flow: يُودع الجميع مباشرةً في main (الجذع) مرة واحدة على الأقل يوميًا. الفروع القصيرة، إن وُجدت، تعيش أقل من 24 ساعة.

يبدو التطوير على الجذع فوضويًا لمن اعتاد الفروع الطويلة، لكنه يعمل بفضل ثلاث ممارسات مكمّلة:

  1. أعلام المميزات (Feature Flags) — العمل غير المكتمل يُشحن خلف علَم مغلق في الإنتاج. سيتعمق الدرس التالي في هذا الموضوع.
  2. الاختبار الآلي الشامل — خط CI يمسك بالانحدارات قبل وصولها إلى main؛ البنية المعطوبة أزمة أولوية قصوى.
  3. البرمجة الثنائية/الجماعية أو دورات مراجعة في نفس اليوم — يُراجع الكود في الوقت الفعلي أو خلال 1-2 ساعة، لا أيام.
# سير عمل التطوير على الجذع اليومي # فرع قصير الأمد (اختياري، أقصاه 1-2 يومين) git switch -c feat/rate-limiter # ... تغييرات واختبارات ... git push origin feat/rate-limiter # PR يُراجع ويُدمج في نفس اليوم gh pr create --base main --fill gh pr merge --squash --delete-branch # في حالة الإيداع المباشر على الجذع (تغيير صغير وآمن) git switch main git pull --rebase # ... تعديل ... git commit -m "fix: correct off-by-one in retry backoff" git push origin main
Three Branching Strategies Side by Side Git Flow main develop feature/* release hotfix متى تستخدمه • برمجيات ذات إصدارات رقمية • إصدارات متاجر التطبيقات أو الفصلية • صيانة إصدارات متعددة متزامنة GitHub Flow main PR #1 PR #2 Deploy متى تستخدمه • منتجات SaaS / نشر مستمر • إصدار واحد نشط في الإنتاج • فرق صغيرة إلى متوسطة Trunk-Based Dev trunk (main) <1 day Feature Flag متى تستخدمه • مؤسسات هندسية عالية السرعة • تغطية اختبارات CI قوية • بنية تحتية لأعلام المميزات جاهزة المزيد من العمليات المزيد من السرعة / الانضباط الإصدار: أسبوعي - فصلي الإصدار: عند كل دمج الإصدار: عدة مرات يوميًا الفريق: أي حجم الفريق: صغير - متوسط الفريق: أي حجم، انضباط عالٍ
مقارنة Git Flow وGitHub Flow والتطوير على الجذع — هيكل الفروع ووتيرة النشر والسياق المثالي لكل منها.

ما تستخدمه الشركات الكبرى فعليًا

الإجابة التجريبية: انتقلت الصناعة بشكل واسع نحو التطوير على الجذع، مع GitHub Flow كحل وسط عملي للفرق الأصغر. نشرت Google وMeta وMicrosoft (الأدوات الداخلية) وLinkedIn وEtsy منشورات هندسية تؤكد اعتمادها للتطوير على الجذع على نطاق واسع. تجد تقارير DORA (أبحاث وتقييم DevOps) باستمرار أن التطوير على الجذع مؤشر إحصائي دال على أداء تسليم البرمجيات المتميز — أوقات تسليم أقصر، وتكرار نشر أعلى، ومعدل فشل تغييرات أدنى.

المُمكِّن الحقيقي ليس الشجاعة — بل البنية التحتية الهندسية: خط CI سريع وشامل (أكثر خطوط Google أقل من 10 دقائق)، ومنصة أعلام مميزات ناضجة (LaunchDarkly أو Unleash أو Flipt أو محلية الصنع)، وثقافة تجعل البنية المعطوبة أولوية فورية لا موضوعًا للوقوف اليومي.

اختيار الاستراتيجية المناسبة لفريقك

طبّق هذه المعايير بالترتيب:

  1. هل تصون إصدارات متعددة منشورة في وقت واحد؟ إن كانت الإجابة نعم، فـ Git Flow (أو نسخة مبسّطة منه مع فروع release/* دائمة فوق GitHub Flow) ضرورة على الأرجح.
  2. هل يمكنك النشر إلى الإنتاج بعد كل دمج؟ إن كانت نعم، ابدأ بـ GitHub Flow. انتقل إلى التطوير على الجذع حين تكون مجموعة الاختبارات شاملة ودورات المراجعة محكمة.
  3. هل خط CI الخاص بك أقل من 15 دقيقة من البداية للنهاية؟ التطوير على الجذع يعمل فقط إذا كانت حلقة التغذية الراجعة سريعة بما يكفي لعدم تجميع المطورين للعمل.
  4. هل لديك أعلام مميزات؟ التطوير على الجذع بدون أعلام يعني شحن مميزات غير مكتملة للمستخدمين. إن لم تتمكن من نشر الأعلام، ابقَ على GitHub Flow حتى تستطيع.
مسار الترحيل العملي: تنجح معظم الفرق بالتحرك من Git Flow إلى GitHub Flow أولًا (توحيد develop في main، وإلزام المراجعة قبل الدمج). وحده هذا يُقلص ألم الدمج بنسبة 70-80%. ثم، حين يصبح CI متينًا والأعلام جاهزة، قصّر عمر الفروع نحو الصفر — هذا هو التطوير على الجذع. القفز مباشرةً من Git Flow إلى التطوير على الجذع يفشل غالبًا لأن البنية التحتية الأساسية لم تكن جاهزة بعد.

فروع الإصدار: الجزء الوحيد من Git Flow الجدير بالإبقاء

حتى الفرق التي تتبع GitHub Flow أو التطوير على الجذع تحتاج أحيانًا إلى فروع إصدار — عند إطلاق تطبيق هاتفي أو حزمة npm أو ملف ثنائي مُجمَّع حيث لا يمكن نشر إصلاح دون تقديم جديد للمتجر أو إبطال CDN. في هذه الحالة، فرع release/vX.Y مقطوع من main عند إيداع الإصدار، يُستخدم حصريًا لإصلاحات حرجة منقولة بـ cherry-pick، هو الأداة الصحيحة. ادمج كل إصلاح فورًا في main باستخدام git cherry-pick (تناولناه في الدرس 3).

# صيانة فرع إصدار بجانب main القائمة على الجذع git switch -c release/v3.2 v3.2.0-tag # قطع من الوسم git push origin release/v3.2 # عند الحاجة لإصلاح حرج على خط الإصدار: git switch main git cherry-pick <fix-sha> # أصلح main أولًا (قاعدة الجذع) git switch release/v3.2 git cherry-pick <fix-sha> # ثم انقل للإصدار git tag -a v3.2.1 -m "Patch: fix payment crash" git push origin release/v3.2 --tags

قاعدة الانضباط: لا شيء يصل إلى فرع الإصدار لم يصل أولًا إلى main. فروع الإصدار آلية تسليم لا بيئة تطوير.

أنماط الفشل الشائعة

  • "GitHub Flow لكن الفروع تعيش أسبوعين" — هذا ليس GitHub Flow، بل Git Flow بطيء بلا هيكل. الفروع الطويلة تُفشل النموذج بأكمله. طبّق حدًا لعمر الفرع في CI (مثل: رفض PRs مفتوحة أكثر من 3 أيام على قاعدة قديمة).
  • تخطي الدمج العكسي في Git Flow — نسيان دمج release/* عكسيًا في develop يعني غياب إصلاحات شحنتها للتو في الإصدار التالي. أدوات Git Flow تؤتمت هذا، لكن سير عمل Git Flow اليدوي يتخطاه دائمًا.
  • التطوير على الجذع بلا اختبارات — الإيداع اليومي على الجذع بلا اختبارات شاملة وسريعة يعني فقط "نحرر جميعًا على نفس الفرع ونأمل الأفضل". الاختبارات شرط مسبق صارم.
  • أعلام المميزات المتروكة إلى الأبد — تتراكم الأعلام كديون تقنية. في Netflix وGoogle، تُحدَّد تواريخ إزالة مجدولة للأعلام لحظة إنشائها. الأعلام القديمة تُسبب حوادث (علَم تُرك مفعّلًا كان ينبغي إزالته أسقط الإنتاج في شركات عديدة).
نتيجة DORA في جملة واحدة: الفرق التي تطبق التطوير على الجذع مع فروع قصيرة الأمد تنشر 208 مرة أكثر وتتعافى من الحوادث أسرع بـ 2604 مرة من الفرق ذات الأداء المنخفض. استراتيجية التفريع التي تختارها ليست تفضيلًا شخصيًا — بل هي رافعة أداء هندسي حقيقية.