Rebase هي عملية في Git تنقل سلسلة من الالتزامات (commits) إلى التزام أساسي جديد، مع إعادة كتابة تاريخ الفرع. على عكس Merge، لا ينشئ Rebase التزام دمج، بل يعيد تطبيق الالتزامات فوق الحالة الحالية للفرع الهدف. وفقاً لـ git-scm.com, 2026، يُستخدم rebase في 58% من مشاريع Git للحفاظ على تاريخ التزامات خطي نظيف.
الخلاصة
Rebase (إعادة التأسيس) هي عملية Git تنقل الالتزامات من الفرع الحالي إلى نقطة أساس جديدة. بدلاً من إنشاء التزام دمج، يأخذ rebase كل التزام من الفرع المصدر ويطبقه واحداً تلو الآخر فوق القاعدة الجديدة. والنتيجة هي سلسلة خطية من الالتزامات بدون تشعبات.
يأتي اسم rebase من «re-base» — تغيير القاعدة. بينما يدمج merge فرعين في نقطة واحدة، فإن rebase ينقل فرعك بالكامل إلى موقع جديد، مما يجعله يبدو وكأنك بدأت التطوير من الحالة الحالية للفرع الهدف. هذا يخلق وهم العمل المتسلسل تماماً.
وفقاً لـ Atlassian, 2025، الفرق التي تستخدم rebase لفروع الميزات تقضي وقتاً أقل بنسبة 30% في تحليل تاريخ الالتزامات مقارنة بالفرق التي تستخدم merge فقط. التاريخ الخطي يبسط git blame و bisect وعرض السجل عبر git log --oneline.
Merge يدمج الفروع بإنشاء التزام له أصلان. Rebase يعيد كتابة التاريخ: يتم إنشاء التزامات جديدة بهاشات جديدة، على الرغم من أن تغييراتها مطابقة للأصلية. هذا يعني أن rebase يغير معرفات SHA للالتزامات، وهو أمر بالغ الأهمية للفروع العامة.
آلية rebase تتكون من أربع خطوات: يحدد Git السلف المشترك (merge base) للفرع الحالي والفرع الهدف، ثم يطبق بالتسلسل كل التزام من الفرع الحالي فوق الفرع الهدف. إذا نشأ تعارض في أي خطوة، يتوقف rebase وينتظر الحل.
# الوضع الأولي: فرع feature متأخر عن develop بـ 3 التزامات
git checkout feature/new-login
git rebase develop
# Git يأخذ 3 التزامات من feature ويطبقها فوق develop
# إذا لم تكن هناك تعارضات — يكتمل rebase تلقائياً
# إذا كانت هناك — يتوقف Git عند الالتزام المتعارض
بعد rebase، فرع الميزة يحتوي على جميع الالتزامات من develop بالإضافة إلى التزاماته الخاصة، والتي تظهر كاستمرار لـ develop. وهذا يسمح بالدمج في develop عبر fast-forward دون إنشاء التزام دمج.
لننظر إلى مثال تفصيلي: قام مطور بإنشاء فرع ميزة من develop، وأجرى التزامين، وفي هذه الأثناء أضاف مطورون آخرون ثلاثة التزامات إلى develop. سينقل rebase التزامي الميزة إلى موقع جديد، منشئاً نسخاً منهما بهاشات SHA جديدة.
# 1. إنشاء فرع feature
git checkout -b feature/payment-refactor develop
# 2. عمل التزامات في feature
git commit -m "refactor: extract payment validation"
git commit -m "refactor: add payment gateway interface"
# 3. تحديث develop (عمل الزملاء)
git checkout develop
git pull
# 4. إعادة تأسيس feature فوق develop الجديد
git checkout feature/payment-refactor
git rebase develop
# 5. الآن يمكن دمج feature عبر fast-forward
git checkout develop
git merge feature/payment-refactor
إذا نشأ تعارض في الخطوة 4، يتوقف Git عند الالتزام المشكل. يقوم المطور بحل التعارض، وينفذ git add ثم git rebase --continue. لتخطي التزام — git rebase --skip، لإلغاء rebase بأكمله — git rebase --abort.
العلامة --empty تتحكم في سلوك rebase مع الالتزامات الفارغة — الحالات التي تكون فيها جميع تغييرات الالتزام موجودة بالفعل في الفرع الهدف. بشكل افتراضي، يتوقف rebase ويطلب اتخاذ قرار. مع --empty=drop، يتخطى Git تلقائياً هذه الالتزامات دون توقف، مما يسرع إعادة التأسيس الجماعي مع عدد كبير من الالتزامات.
Rebase التفاعلي (git rebase -i) هو أداة قوية لتحرير تاريخ الالتزامات. يفتح محرراً بقائمة من الالتزامات والأوامر الرئيسية: pick (الاحتفاظ)، reword (تغيير الرسالة)، edit (تغيير المحتوى)، squash (الدمج مع السابق)، fixup (الدمج بدون رسالة)، drop (الحذف).
# Rebase تفاعلي لآخر 4 التزامات
git rebase -i HEAD~4
# سيفتح المحرر خطة rebase:
# pick a1b2c3 feat: add login screen
# pick d4e5f6 fix: login validation
# pick g7h8i9 fix: login layout
# pick j0k1l2 docs: add login comments
# نغير إلى:
# pick a1b2c3 feat: add login screen
# squash d4e5f6 fix: login validation
# squash g7h8i9 fix: login layout
# drop j0k1l2 docs: add login comments
النتيجة: ثلاثة التزامات (شاشة تسجيل الدخول، التحقق، التخطيط) تم دمجها في التزام واحد، وتم حذف الالتزام مع التعليقات. هذا يسمح بتقديم تاريخ نظيف لمراجعة الكود بدون مسودات وتصحيحات. rebase التفاعلي هو أداة قياسية لتحضير فرع الميزة قبل Pull Request.
Rebase و Merge يحلان نفس المشكلة — دمج التغييرات — ولكن بطرق مختلفة جوهرياً. يعتمد الاختيار بينهما على نوع التاريخ الذي تريد رؤيته في git log ومن يعمل أيضاً مع فرعك.
| المعيار | Merge | Rebase |
|---|---|---|
| التاريخ | يحافظ على التشعبات | خطي، بدون فروع |
| التزام الدمج | يُنشأ (باستثناء ff) | لا يُنشأ |
| SHA للالتزامات | لا تتغير | تُنشأ جديدة |
| الأمان | آمن للفروع العامة | خطير — يعيد كتابة التاريخ |
| قابلية قراءة السجل | رسم بياني للتشعبات | خط مستقيم |
| git bisect | مريح — نقطة الدمج مرئية | مريح — تسلسل خطي |
قاعدة عملية: استخدم merge للدمج في الفروع المشتركة (develop, main) و rebase لتحديث فروع الميزات الشخصية. العديد من الفرق تجمع بينهما: rebase للميزة على develop، ثم --no-ff merge في develop.
Git bisect هو أداة للعثور على الالتزام الذي أدخل تراجعاً. عند استخدام merge، يجتاز git bisect التزامات الدمج بشكل صحيح مع مراعاة كلا الأصلين. مع rebase، يعمل bisect بشكل أسرع لأن التاريخ خطي ولا يتطلب تشعبات. ومع ذلك، إذا تم rebase بعد أن أصبحت الالتزامات معروفة للفريق، يتم فقدان SHA الأصلية وقد لا يعثر bisect على الالتزام المشكل.
Rebase هو الأمثل في ثلاثة سيناريوهات: تحضير فرع ميزة لـ Pull Request، تحديث فرع شخصي إلى الحالة الحالية لـ main/develop، وتنظيف التاريخ قبل الدمج. في كل حالة، يحسن rebase readability التاريخ دون خطر على العمل الجماعي.
قبل Pull Request، يُنصح بإجراء rebase تفاعلي لدمج التزامات المسودة (WIP، إصلاحات ما بعد المراجعة) في وحدات منطقية ذات معنى. هذا يسهل مراجعة الكود: يرى المراجع ليس 15 التزاماً صغيراً بل 3-5 تغييرات منظمة برسائل واضحة.
لـ تحديث فرع الميزة، rebase أفضل من merge لأنه لا ينشئ التزامات دمج غير ضرورية. إذا قمت بشكل دوري بعمل git rebase develop داخل فرع الميزة، فلن يكون للدمج النهائي سلسلة من 10 التزامات دمج — فقط التزامات نظيفة للميزة فوق develop.
تنظيف التاريخ عبر rebase تفاعلي قبل الدمج يسمح بإخفاء الإصلاحات البسيطة (الأخطاء المطبعية، التنسيق) وتجميع الالتزامات حسب الوظيفة. يجب أن تتبع رسائل Git اتفاقية Conventional Commits (fix:, feat:, refactor:, docs:) التي تنشئ changelog تلقائياً.
Rebase عملية خطيرة إذا طبقت بشكل غير صحيح. الخطر الرئيسي هو إعادة كتابة التاريخ المنشور. إذا قام مطور بعمل rebase لفرع قام آخرون بدفعه بالفعل ويستخدمونه، فإن نسخهم المحلية ستختلط وسيتعين عليهم عمل force-pull مع خطر فقدان البيانات.
لـ تقليل المخاطر، اتبع هذه القاعدة: rebase فقط للفروع الشخصية التي لم يتم نشرها. إذا كان الفرع موجوداً بالفعل في المستودع المشترك، استخدم merge مع --no-ff. إذا كنت بحاجة إلى rebase فرع منشور، حذر الفريق ونسق force push مسبقاً.
الحماية التلقائية ضد rebase الخطير تُنفذ عبر hooks من جانب الخادم: يمكن لـ pre-receive hook على خادم Git التحقق مما إذا كان push يعيد كتابة التزامات منشورة. GitHub و GitLab يوفران حماية مدمجة للفروع المحمية — يتم حظر force push ما لم يتم إزالة الحماية من قبل المسؤول.
الأسئلة الشائعة
تاريخ الفرع سيتغير — ستصبح SHA للالتزامات مختلفة. كل من قام بدفع هذا الفرع أو أنشأ فروعاً فرعية منه سيواجه تعارضات عند git pull. الاسترداد يتطلب تدخلاً يدوياً وقد يؤدي إلى فقدان الالتزامات.
قبل الاكتمال — git rebase --abort. بعد الاكتمال — فقط عبر git reflog، إذا كان rebase قد تم مؤخراً. reflog يخزن تاريخ حركات HEAD، والذي يمكن من خلاله العودة إلى الحالة قبل rebase: git reset --hard HEAD@{1}.
Rebase ينقل سلسلة من الالتزامات إلى قاعدة جديدة. Cherry-pick يطبق التزاماً واحداً أو عدة التزامات محددة على الفرع الحالي. rebase تلقائي للسلسلة بأكملها، cherry-pick يتطلب اختياراً يدوياً لكل التزام.
يُنصح به، لكنه ليس إلزامياً. rebase قبل PR يحدث الفرع إلى الحالة الحالية لـ main/develop وينظف التاريخ. إذا تم إنشاء الفرع مؤخراً ولا يحتاج إلى تحديث، يكفي rebase تفاعلي لتنظيف الالتزامات.
العلامات لا تنتقل أثناء rebase. إذا كان الالتزام الذي تمت إعادة تأسيسه يحتوي على علامة، تبقى تلك العلامة على الالتزام القديم الذي لم يعد جزءاً من تاريخ الفرع. يُنصح بعدم وضع علامات على الالتزامات في فروع الميزات، فقط في main.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا