Rebase — بازنویسی تاریخچه برای خط تمیز

انتقال کامیت‌ها به پایه جدید با git rebase، تفاوت با merge و قانون طلایی استفاده امن از rebase.

Rebase چیست؟

git rebase کامیت‌های شاخه شما را برمی‌دارد و دوباره روی یک پایه جدید می‌نویسد (re-base = باز-پایه‌گذاری). نتیجه: تاریخچه خطی و تمیز بدون کامیت‌های merge زیاد.

مشکلی که rebase حل می‌کند

شاخه شما از main جدا شده، اما main هم پیش رفته. حالا می‌خواهید شاخه‌تان آخرین تغییرات main را داشته باشد:

وضعیت فعلی:
      A---B---C---D  (main)
               \
                E---F  (feature)

دو راه:

راه ۱: merge (که بلدید)

git switch feature
git merge main
# کامیت merge ساخته میشود:
      A---B---C---D---------M  (feature)
               \         /
                E---F---

کار می‌کند، اما تاریخچه پر از کامیت‌های merge می‌شود.

راه ۲: rebase (تمیزتر)

git switch feature
git rebase main
# Successfully rebased and updated refs/heads/feature.

کامیت‌های E و F انگار از D جدا شده‌اند:

      A---B---C---D  (main)
                    \
                     E"---F"  (feature)

تاریخچه کاملاً خطی شد! (E" و F" کپی‌های جدید با شناسه متفاوت‌اند)

rebase در عمل

# ۱. به شاخه‌ای بروید که می‌خواهد rebase شود:
git switch feature

# ۲. rebase روی main:
git rebase main

# ۳. اگر تعارض شد:
#    فایل‌ها را حل کنید، بعد:
git add .
git rebase --continue

# یا فرار از کل rebase:
git rebase --abort

تعارض در rebase

برخلاف merge که یک‌جا تعارض می‌دهد، rebase کامیت به کامیت جلو می‌رود و ممکن است چند بار تعارض ببینید:

CONFLICT (content): Merge conflict in app.py
error: could not apply E... کامیت اول feature
hint: Resolve all conflicts manually, mark them as resolved with "git add"

برای هر کامیت: حل کنید → git add . → git rebase --continue

Interactive Rebase — قدرتمندترین ابزار

با -i می‌توانید کامیت‌های شاخه را بازآرایی کنید:

git rebase -i main

ویرایشگر لیست کامیت‌ها را نشان می‌دهد:

pick a1b2c3d کامیت اول
pick e5f6g7h کامیت دوم
pick i9j0k1l کامیت سوم

با تغییر pick به:

دستورکار
pickهمان‌طور که هست نگه دار
squashبا کامیت قبلی یکی کن (ادغام!) ⭐
rewordفقط پیام را عوض کن
dropحذف کامیت
editتوقف برای ویرایش محتوا

مثال معروف: ۵ کامیت «کار نیمه‌کاره» را در یک کامیت تمیز squash کنید قبل از PR!

⚠️ قانون طلایی Rebase

هرگز شاخه‌ای را که دیگران هم استفاده می‌کنند (push شده و عمومی است) rebase نکنید! چون rebase شناسه کامیت‌ها را عوض می‌کند، تاریخچه دو نسخه ناسازگار می‌شود — کابوس واقعی برای تیم.

قانون عملی:

merge یا rebase؟

ویژگیmergerebase
تاریخچهواقعی (همان‌طور که بود)خطی و تمیز (بازنویسی‌شده)
کامیت اضافهکامیت merge می‌سازدنه
امنیت برای شاخه عمومی✅❌
تعارضیک‌جاممکن است چند بار
ترفند حفظ«واقعیت را نگه دار»«تمیزی را نگه دار»
خیلی از تیم‌ها ترکیبی کار می‌کنند: rebase محلی برای به‌روز ماندن + merge برای ادغام نهایی در main. یا در گیت‌هاب دکمه Rebase and merge را برای PR استفاده می‌کنند.

خلاصه

این مبحث بخشی از دوره آموزش کامل Git است.

ابزارهای مرتبط