Rebase: ما هو، كيفية عمل rebase والتعامل مع Git

المؤلف: IT Sectr نُشر: 2026-08-01 وقت القراءة: 9 دق

Rebase هي عملية في Git تنقل الـ commits من فرع إلى قمة فرع آخر، مما ينشئ تاريخًا خطيًا بدون commits merge غير ضرورية. على عكس الدمج، يعيد rebase كتابة التاريخ: كل commit منقول يحصل على تجزئة جديدة لأن والده يتغير. وفقًا لوثائق Git (2026)، يُستخدم rebase لمزامنة فروع الميزات مع أحدث حالة لـ main قبل إنشاء طلب سحب. أمر git rebase هو أحد الأدوات الرئيسية للحفاظ على تاريخ نظيف في المشاريع التي تستخدم Git Flow.

النقاط الرئيسية

  • Rebase — ينقل commits فرع الميزات إلى قمة الفرع المستهدف مع إنشاء تجزئات جديدة.
  • تاريخ خطي — الميزة الرئيسية لـ rebase: عدم وجود commits merge يبسط قراءة سجل التغييرات.
  • Rebase تفاعلي مع العلم -i يسمح بدمج وإعادة تسمية وحذف الـ commits قبل النشر.
  • الفروع العامة — rebase محظور للفروع التي يعمل عليها مطورون آخرون لأنه يعيد كتابة التاريخ.
  • احتمال وجود تعارضات — عند نقل الـ commits، قد يطلب Git حل التعارضات لكل commit على حدة.

ما هو Rebase في Git

Rebase هو أمر Git يعيد توجيه الفرع الحالي إلى فرع محدد: يأخذ جميع commits الفرع الحالي، يحفظها مؤقتًا، ينقل مؤشر الفرع إلى commit الهدف، ويطبق الـ commits المحفوظة تباعًا فوقه. النتيجة — يبدو التاريخ كما لو أن المطور عمل مباشرة من آخر commit للفرع الهدف.

الصيغة الأساسية: git rebase main — أثناء وجودك في فرع ميزات، هذا الأمر ينقل جميع commits الفرع إلى قمة main. يستخدم Git استراتيجية الدمج ثلاثي الاتجاه لكل commit على حدة. إذا كان commit A موجودًا بالفعل في الفرع الهدف (يُحدد بالتجزئة)، يتخطاه Git تلقائيًا، متجنبًا التغييرات المكررة.

يدعم Rebase أيضًا وضع onto لنقل مجموعة جزئية من الـ commits: git rebase --onto target start end — هذه الصيغة تسمح باستخراج نطاق من الـ commits من فرع وتطبيقها فوق فرع آخر. على سبيل المثال، git rebase --onto main feature~3 feature ينقل آخر ثلاثة commits من فرع feature فوق main.

bash
# Switch to feature branch
git checkout feature

# Rebase feature onto main
git rebase main

# After successful rebase — history is linear
git log --oneline --graph

# Move last 3 commits to main
git rebase --onto main HEAD~3 HEAD

Rebase vs Merge: الفروق الرئيسية

Rebase و merge يحلان نفس المهمة — دمج التغييرات من فروع مختلفة — لكنهما يفعلان ذلك بطرق مختلفة جوهريًا. Merge يحافظ على تاريخ الدمج الكامل عن طريق إنشاء commit merge بوالدين. Rebase يعيد كتابة التاريخ، مما يجعله خطيًا. يعتمد الاختيار بينهما على سير عمل الفريق وقواعد إدارة المستودع.

الفرق الرئيسي هو كيفية تسجيل حقيقة الدمج. Merge يحافظ: «في هذه النقطة دمجنا feature في main» — هذا مفيد لتاريخ المشروع لكنه يثقل السجل بعمليات دمج متكررة. Rebase يظهر: «تم عمل commits feature تباعًا من آخر حالة لـ main» — هذا نظيف لكنه يخفي حقيقة أن التطوير تم بالتوازي.

الفرق الثاني هو معالجة التعارضات. مع merge، تُحل التعارضات مرة واحدة ويُسجل الحل في commit merge. مع rebase، يمكن أن تنشأ تعارضات لكل commit منقول، وكل منها يتطلب حلاً منفصلاً. هذا أكثر استهلاكًا للوقت لكنه يتيح تحكمًا أدق في التغييرات التي تصل إلى النسخة النهائية.

المعيارRebaseMerge
التاريخخطي، بدون commits mergeغير خطي، مع commits merge
تجزئات commitsتُعاد كتابتها (جديدة)تُحفظ الأصلية
التعارضاتلكل commit على حدةمرة واحدة في commit merge
الفروع العامةمحظورمسموح
أمر التراجعgit rebase --abortgit merge --abort

Rebase التفاعلي: الأوامر والأعلام

Rebase التفاعلي (git rebase -i) هو وضع يفتح فيه Git محررًا بقائمة من الـ commits والإجراءات المتاحة لكل منها. يمكن للمطور إعادة كتابة التاريخ قبل الإرسال إلى مستودع بعيد. هذه هي الأداة الرئيسية للحفاظ على commits نظيفة في فرع الميزات.

الأوامر المتاحة في الوضع التفاعلي: pick (إبقاء commit كما هو)، reword (تغيير رسالة commit)، edit (التوقف للتغيير)، squash (الدمج مع commit السابق مع الاحتفاظ بكلتا الرسالتين)، fixup (الدمج مع تجاهل الرسالة)، drop (حذف commit). يوضع كل أمر قبل تجزئة commit في المحرر المفتوح.

Squash و fixup هما الأمران الأكثر استخدامًا لدمج الـ commits. إذا قام المطور بعمل 5 commits صغيرة للتصحيح أثناء العمل، squash يدمجها في commit منطقي واحد برسالة ذات معنى. Fixup مفيد لتصحيح الأخطاء المطبعية: تذهب التغييرات إلى commit السابق دون الاحتفاظ برسالتها الخاصة.

bash
# Open editor for last 4 commits
git rebase -i HEAD~4

# Editor will show:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests

# After saving — Git performs rebase
# and opens editor for squashed commit message

# Auto-squash without opening editor
git rebase -i HEAD~4 --autosquash

العلم --autosquash يرتب تلقائيًا fixup/squash للـ commits التي تبدأ رسائلها بـ fixup! أو squash!. هذا يُسرع العمل إذا كان المطور يحدد الـ commits مسبقًا للدمج لاحقًا. العلم --committer-date-is-author-date يحافظ على تاريخ commit الأصلي عند إعادة التوجيه — مفيد للحفاظ على الترتيب الزمني في التاريخ.

حل التعارضات أثناء Rebase

التعارضات أثناء rebase تحدث عندما لا يستطيع Git تطبيق commit منقول تلقائيًا بسبب تعارض مع التغييرات في الفرع الهدف. على عكس merge، حيث يُحل التعارض مرة واحدة، مع rebase يمكن لكل commit أن يسبب تعارضًا، ويجب حله تباعًا لكل commit من الأقدم إلى الأحدث.

عند حدوث تعارض، Git يوقف rebase ويُبلغ عن commit الذي تسبب بالمشكلة. يفتح المطور الملف المتعارض (يحدد Git مناطق التعارض بعلامات <<<<<<<, =======, >>>>>>>)، يحرره، يضيفه إلى الفهرس (git add)، ويواصل rebase بأمر git rebase --continue. إذا لم يُوجد حل — git rebase --abort يلغي rebase بالكامل.

نصيحة: مع تعارضات متعددة، من الأكثر فعالية استخدام git mergetool، الذي يفتح محررًا مرئيًا لحل التعارضات. يمكن أيضًا تخطي commit المشكل (git rebase --skip)، لكن هذا يزيل تغييراته من التاريخ النهائي، وهو نادرًا ما يكون القرار الصحيح.

bash
# Start rebase with conflict
git rebase main
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt

# Check status
git status
# both modified: file.txt

# Edit conflicted sections → git add → continue
git add file.txt
git rebase --continue

# If uncertain — abort
git rebase --abort

متى لا يجب عمل Rebase

القاعدة الذهبية لـ rebase: لا تعيد توجيه commits تم إرسالها بالفعل إلى مستودع بعيد ومتاحة لمطورين آخرين. نظرًا لأن rebase يعيد كتابة تجزئات commits، سيواجه الزملاء تعارضات عند محاولة المزامنة — سيتعارض تاريخهم المحلي مع التاريخ البعيد المعاد كتابته.

موقف يكون فيه rebase محظورًا تمامًا: إذا كان شخص ما قد أنشأ بالفعل فرعًا بناءً على commits الخاصة بك (على سبيل المثال، زميل أنشأ فرعًا من فرع الميزات الخاص بك)، إعادة كتابة التاريخ ستعطل عمله. في هذه الحالات، استخدم merge. كما لا يُنصح بعمل rebase قبل موعد التسليم مباشرة — خطأ في حل التعارضات قد يستغرق وقتًا أطول من المتوقع ويعطل الإصدار.

استثناء: إذا كان الفرع يستخدمه مطور واحد فقط (فرع ميزات شخصي، غير منشور أو منشور في وضع المسودة)، rebase قبل الدفع هو ممارسة قياسية. بعد النشر وبدء العمل الجماعي — فقط merge. تقدم GitHub و GitLab افتراضيًا squash merge كحل وسط: يدمج commits في واحد لكنه لا يعيد كتابة تاريخ الفرع الهدف.

  • الفروع العامة (main, develop, release) — rebase محظور تمامًا.
  • Commits الآخرين — إذا كان الفرع يحتوي على commits لمطور آخر، rebase غير مسموح.
  • قبل الإصدار — مخاطر التعارضات أكبر: merge أكثر أمانًا قبل يوم من الموعد النهائي.
  • فروع مع علامات — نقل commit مع علامة ينتهك اتفاقيات الإصدار الدلالي.
  • CI/CD مرتبط بالتجزئات — بعض أنظمة النشر تحدد الإصدارات بتجزئة commit؛ rebase سيكسر التتبع.

سير العمل العملي مع Rebase

تستخدم الفرق الحديثة غالبًا سير عمل موجه نحو rebase مع GitHub Flow. تبدو العملية كالتالي: ينشئ المطور فرع ميزات من main، يعمل فيه، يتزامن دوريًا عبر git rebase main، وقبل إنشاء طلب سحب يقوم بـ rebase تفاعلي لتنظيف التاريخ.

بعد إنشاء PR (إذا لزم الأمر سحب تغييرات جديدة من main)، يُستخدم git pull --rebase main بدلاً من git pull العادي. هذا يسحب التغييرات دون إنشاء commit merge غير ضروري. Git pull مع العلم --rebase يعادل git fetch + git rebase — يقوم Git أولاً بتنزيل commits جديدة، ثم يعيد توجيه التغييرات المحلية فوقها.

يسمح Git بتكوين rebase كسلوك افتراضي لـ pull: git config --global pull.rebase true. بعد هذا الإعداد، git pull دائمًا ينفذ rebase بدلاً من merge. إذا لزم الأمر pull عادي — يُستخدم git pull --no-rebase. العديد من الفرق تفعل autostash أيضًا: git config --global rebase.autoStash true — هذا يخفي تلقائيًا التغييرات غير الملتزمة قبل rebase ويعيدها بعده.

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

ماذا يعني إعادة تأسيس commits في Git؟

إعادة التأسيس تعني تنفيذ git rebase: نقل commits الفرع الحالي إلى قمة فرع آخر. النتيجة — يصبح التاريخ خطيًا، كل commit يحصل على تجزئة جديدة، ولا تُنشأ commits merge. يُستخدم الأمر لمزامنة الفروع دون نقاط دمج غير ضرورية في السجل.

كيف يختلف rebase عن merge؟

Merge ينشئ commit merge بوالدين، محافظًا على التاريخ المتوازي والتجزئات الأصلية. Rebase يعيد كتابة التاريخ — تحصل commits على تجزئات جديدة ويصبح التاريخ خطيًا. Merge أكثر أمانًا للفروع العامة، rebase يعطي سجلاً أنظف.

كيف عمل rebase تفاعلي؟

أمر git rebase -i HEAD~N يفتح محررًا بآخر N commits. لكل commit يمكن اختيار إجراء: pick (إبقاء)، reword (إعادة تسمية)، edit (تعديل)، squash (دمج مع السابق)، fixup (دمج بدون رسالة)، drop (حذف). بعد الحفظ، يطبق Git التغييرات المختارة.

لماذا rebase خطير على الفروع العامة؟

Rebase يعيد كتابة تجزئات commits، مما يجعل التاريخ غير متوافق مع نسخ نفس commits على أجهزة المطورين الآخرين. إذا كان زميل قد حصل بالفعل على commits الخاصة بك عبر git pull، ثم قمت بإعادة توجيهها، سيتم رفض git push الخاص به، وسينشئ git pull commits مكررة وتعارضات.

هل يمكن التراجع عن rebase بعد اكتماله؟

قبل الاكتمال — git rebase --abort يلغي بالكامل. بعد الاكتمال، يمكن استعادة الحالة السابقة عبر git reflog — العثور على تجزئة commit قبل rebase وتنفيذ git reset --hard إليه. Reflog يخزن تاريخ حركات HEAD لمدة 30 يومًا افتراضيًا.

الخلاصة

  • Rebase — عملية تنقل commits إلى قاعدة جديدة، منشئة تاريخًا خطيًا بدون commits merge.
  • أمر git rebase main يعيد توجيه الفرع الحالي على main، مطبقًا commits تباعًا فوقه.
  • الوضع التفاعلي -i يسمح بدمج (squash) وإعادة تسمية (reword) وحذف (drop) الـ commits.
  • التعارضات أثناء rebase تُحل لكل commit على حدة، على عكس merge.
  • الفروع العامة لا يجب إعادة توجيهها — هذا يكسر التاريخ لمطورين آخرين.
  • git pull --rebase — طريقة آمنة للمزامنة مع فرع بعيد بدون commit merge.
  • Git reflog يسمح بالاسترداد بعد rebase فاشل في غضون 30 يومًا.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا