Git 2026

فصل ۲۳ · Rebase تعاملی

Rebase تعاملی — بازنویسی تاریخچه مثل مجسمه‌ساز

Rebase کامیت‌های شاخهٔ تو را برمی‌دارد و یکی‌یکی روی نوک یک شاخهٔ دیگر دوباره اعمال می‌کند. نتیجه تاریخچهٔ خطی است، ولی هش هر کامیت عوض می‌شود. فقط روی شاخه‌ای که دیگران از آن استفاده نمی‌کنند این کار را بکن.

🎯 اهداف یادگیری

  • rebase را به‌عنوان «کامیت‌ها را روی پایهٔ جدید دوباره پخش کن» توضیح دهی
  • rebase -i را برای squash و reword به کار ببری
  • --autosquash و fixup! را بلد باشی
  • قانون طلایی را هرگز نشکنی
merge در برابر rebase

شکل ۱۶ — rebase کامیت‌های جدید می‌سازد (D′ و E′)؛ هش عوض می‌شود.

🧠 rebase دقیقاً چه می‌کند؟

Git هر کامیت شاخهٔ تو را که در main نیست برمی‌دارد، main را HEAD می‌کند، و وصله‌ها را یکی‌یکی اعمال می‌کند. نتیجه: تاریخچهٔ خطی. هزینه: هویت جدید برای هر کامیت.

به‌روز کردن شاخهٔ شخصی
git fetch origin
git switch feat/auth
git rebase origin/main
git push --force-with-lease
🖥️ VS Code Git
  • ... → Pull (Rebase) برای به‌روز کردن شاخه
  • Palette: Git: Rebase Branch... → origin/main
  • تعارض: Merge Editor → Stage → Git: Rebase Continue
  • نوار زرد بالای ادیتور یعنی rebase ناتمام است — کامیت عادی نزن
  • Git: Rebase Abort برای پشیمانی
⌨️ Terminal

git fetch origin git rebase origin/main git rebase --continue git rebase --abort git push --force-with-lease

🎛️ interactive — اتاق عمل

پنج کامیت آخر را ویرایش کن
git rebase -i HEAD~5

ویرایشگر (در این کتاب VS Code با core.editor="code --wait") لیستی می‌آورد:

todo
pick a11 feat: add login form
pick b22 fix: typo in label
pick c33 wip
pick d44 feat: wire submit
pick e55 docs: readme

فرمان‌ها:

فرمان معنی
pick نگه دار
reword پیام را عوض کن
edit بایست؛ فایل را درست کن
squash با قبلی یکی کن؛ پیام‌ها را ترکیب کن
fixup با قبلی یکی کن؛ پیام را دور بریز
drop حذف

ترتیب خطوط = ترتیب تاریخچه. جابه‌جا کن تا داستان منطقی شود.

هرگز rebase روی کامیت عمومی

اگر origin/main یا شاخه‌ای که همکارت checkout کرده شامل آن هش‌هاست، rebase = دو تاریخچهٔ موازی و force-push جنگی.

⚡ fixup و autosquash

بعد از ریویو، بدون کامیت «address comments»
git commit --fixup a11
git rebase -i --autosquash origin/main

--fixup پیامی مثل fixup! feat: add login form می‌سازد؛ autosquash آن را زیر هدف می‌چسباند. در Git جدید git commit --squash هم هست.

از Git ۲.۳۸+ پرچم --update-refs شاخه‌های محلی دیگری که به کامیت‌های بازنویسی‌شده اشاره می‌کردند را هم حرکت می‌دهد — نجات از شاخه‌های یتیم.

🧩 تعارض وسط rebase

نجات
# فایل را در VS Code حل و Stage کن
git rebase --continue
git rebase --abort          # پشیمانی کامل
git rebase --skip           # این وصله را دور بینداز — خطرناک

rerere (فصل ۲۴) تعارض تکراری را به خاطر می‌سپارد.

VS Code

وضعیت rebase را نوار زرد بالای ادیتور نشان می‌دهد. Merge Editor همان UI تعارض فصل ۷ است. تا نوار زرد هست، کامیت عادی نزن.

سؤالات مصاحبه (با پاسخ)

Mid — چرا PR بعد از rebase «جدید» به نظر می‌رسد؟ چون هش عوض شده؛ GitHub فایل‌ها را مقایسه می‌کند نه هش را. Force-with-lease لازم است.

Senior — rebase در برابر merge برای به‌روز کردن شاخه؟ rebase تاریخچهٔ PR را خطی و خوانا می‌کند؛ merge یک گره همگام‌سازی اضافه می‌کند. تیم باید یکی را انتخاب کند.

✅ چک‌لیست فهم

  • rebase فقط روی شاخهٔ خودت
  • fixup + autosquash را بلدی
  • --abort عضله‌ای شده
  • force خام نمی‌زنی

فصل بعد: cherry-pick، revert پیشرفته و rerere.

فصل ۲۳ از ۳۶ · مرجع جامع و حرفه‌ای Git و GitHub · ویرایش 1.0.0