ملحق: الفرق بين git merge و git rebase

4 دقيقة

السياق

في هذا المثال، لدينا مستودع بفرع رئيسي main يحتوي ملف أساس fichier1.txt وأول إيداع أولي. انطلاقاً من main، ننشئ فرعين، branche1 و branche2، كل منهما مخصَّص لاختبار rebase و merge على التوالي. ثم يُنشأ فرعا عمل إضافيان، branche-rebase من branche1 و branche-merge من branche2، لإضافة تعديلات عليهما.

السجل الأولي

يبدأ المشروع بمستودع يحتوي إيداعاً واحداً على main، يقابل إنشاء الملف fichier1.txt:

plaintext
(main)
A               # Commit initial avec fichier1.txt

في الإيداع A، أضفنا الملف fichier1.txt بمحتوى أولي.

ثم يُنشأ فرعان جديدان من main:

  1. branche1: مخصَّص لاستقبال branche-rebase لاختبار git rebase.
  2. branche2: مخصَّص لاستقبال branche-merge لاختبار git merge.

العمل في كل فرع عمل

في كل فرع عمل (branche-rebase و branche-merge)، نجري ثلاثة إيداعات منفصلة. إليك الإيداعات بالتفصيل لكل فرع:

plaintext
(main)
A

(branche-rebase)
       \
        D---E---F   # Commits ajoutés sur branche-rebase

(branche-merge)
       \
        G---H---I   # Commits ajoutés sur branche-merge
  1. الإيداعات على branche-rebase:

    • الإيداع D: إنشاء الملف fichier-2-rebase.txt بالمحتوى الأولي "Modification 1 dans branche-rebase".
    • الإيداع E: إضافة "Modification 2 dans branche-rebase" في الملف نفسه fichier-2-rebase.txt.
    • الإيداع F: إضافة "Modification 3 dans branche-rebase" في الملف نفسه fichier-2-rebase.txt.
  2. الإيداعات على branche-merge:

    • الإيداع G: إنشاء الملف fichier-2-merge.txt بالمحتوى الأولي "Modification 1 dans branche-merge".
    • الإيداع H: إضافة "Modification 2 dans branche-merge" في الملف نفسه fichier-2-merge.txt.
    • الإيداع I: إضافة "Modification 3 dans branche-merge" في الملف نفسه fichier-2-merge.txt.

تضيف هذه الإيداعات محتوى مطابقاً، لكن في ملفات مختلفة (fichier-2-rebase.txt و fichier-2-merge.txt)، للسماح بمقارنة واضحة بين merge و rebase.


الخطوة 1: دمج branche-merge في branche2 بـ git merge

لدمج تعديلات branche-merge في branche2، نستخدم الأمر git merge على branche2. تنشئ هذه العملية إيداع دمج يحفظ سجلاً كاملاً ويتضمّن إيداعات فرع العمل دون إعادة ترتيبها.

السجل بعد merge:

plaintext
(branche2)
A-------J        # J est le commit de fusion
 \       |
  \      |
   G---H---I     # branche-merge conserve son historique distinct
  • شرح الإيداعات:
    • الإيداع J: إيداع دمج يجمع محتوى branche2 مع تعديلات branche-merge (G، H، I) دون نقلها أو تغيير ترتيبها.
  • ملاحظة: مع git merge، يُظهر السجل «نقطة التقاء» تشير بصرياً إلى مكان دمج branche-merge في branche2. يحفظ ذلك سجلاً كاملاً ومميّزاً لكل فرع، وهو غالباً مفيد في المشاريع التعاونية.

الخطوة 2: دمج branche-rebase في branche1 بـ git rebase

لدمج تعديلات branche-rebase في branche1، نستخدم الأمر git rebase. بخلاف merge، تعيد إعادة الأساس تموضع الإيداعات (D، E، F) لـ branche-rebase كأنها أُنشئت بعد آخر إيداع في branche1 (A).

السجل بعد rebase:

plaintext
(branche1)
A---D'---E'---F'   # Commits de branche-rebase réappliqués en fin de branche1
  • شرح الإيداعات:
    • الإيداعات D'، E'، F': إيداعات معاد تشغيلها من branche-rebase مطبَّقة خطّياً بعد A على branche1.
  • ملاحظة: مع git rebase، تُعاد تنظيم إيداعات branche-rebase لتشكيل سجل خطّي بلا «نقطة التقاء»، كأنها أُضيفت مباشرة بعد الإيداع الأولي A. يبسّط ذلك السجل ويجعله أنظف، لكنه قد يخفي مسار فروع العمل الأولية.

المقارنة النهائية

الفروقات المرصودة في سجلات Git تسمح بفهم أفضل للاستخدامات الخاصة لـ merge و rebase.

  • git merge:

    • الأثر: يحافظ على سجل كامل مع إيداع دمج يعلّم التقاء الفروع.
    • المزية: مثالي لتتبّع سجل كامل في المشاريع التعاونية، لأن كل التقاء ظاهر.
    • العيب: قد يصبح السجل معقّداً مع كثرة الالتقاءات، خاصة في المشاريع ذات الفروع المتعددة.
  • git rebase:

    • الأثر: يعيد تنظيم الإيداعات لوضعها خطّياً في نهاية الفرع الرئيسي، بلا إنشاء إيداع دمج.
    • المزية: مثالي لسجل خطّي ونظيف، مع تقليل الالتقاءات. غالباً ما يُفضَّل في المشاريع الصغيرة أو لتنظيف السجل قبل مشاركته.
    • العيب: قد يخفي مسار فروع العمل، مما قد يسبّب مشكلة إن عمل عدة أشخاص على الفروع نفسها.

الملخص

الأمرالسجلحالة الاستخدام المثالية
git mergeسجل كامل مع نقطة التقاءمشاريع تعاونية بعدة فروع
git rebaseسجل خطّي بلا نقاط التقاءتنظيف السجل قبل دمج مشترك

باختصار:

plaintext
git merge   ->  Historique complet avec commit de fusion
git rebase  ->  Historique linéaire sans commit de fusion

يسمح لك هذا الدليل بفهم الفروقات بين git merge و git rebase وتصوّرها، واختيار الطريقة الأنسب حسب سياق مشروعك.