Rebase — عملیاتی در Git است که دنبالهای از commitها را به یک commit پایه جدید منتقل میکند و تاریخچه شاخه را بازنویسی میکند. برخلاف Merge، Rebase یک commit ادغام ایجاد نمیکند، بلکه commitها را روی وضعیت فعلی شاخه مقصد دوباره اعمال میکند. به گزارش git-scm.com، 2026، از rebase در 58% پروژههای Git برای حفظ تاریخچه commit خطی و تمیز استفاده میشود.
نکات اصلی
Rebase (تغییر پایه) — عملیات Git است که commitها را از شاخه فعلی به یک نقطه مرجع جدید (پایه) منتقل میکند. به جای ایجاد commit ادغام، rebase هر commit را از شاخه مبدأ گرفته و به ترتیب روی پایه جدید اعمال میکند. نتیجه یک دنباله خطی از commitها بدون انشعاب است.
نام rebase از «re-base» — تغییر پایه گرفته شده است. اگر merge دو شاخه را در یک نقطه ترکیب کند، rebase در واقع کل شاخه شما را به مکان جدیدی منتقل میکند و این توهم را ایجاد میکند که کار را از وضعیت فعلی شاخه مقصد شروع کردهاید. این امر توهم کار کاملاً متوالی را ایجاد میکند.
به گزارش Atlassian، 2025، تیمهایی که از rebase برای شاخههای feature استفاده میکنند، 30% زمان کمتری برای تحلیل تاریخچه commit نسبت به تیمهایی که صرفاً از merge استفاده میکنند، صرف میکنند. تاریخچه خطی git blame، bisect و مشاهده لاگ از طریق git log --oneline را ساده میکند.
Merge شاخهها را با ایجاد یک commit با دو والد ترکیب میکند. Rebase تاریخچه را بازنویسی میکند: commitهای جدید با hashهای جدید از نو ایجاد میشوند، اگرچه تغییرات در آنها با اصل یکسان است. این بدان معناست که rebase شناسههای SHA commitها را تغییر میدهد که برای شاخههای عمومی حیاتی است.
مکانیزم rebase از چهار مرحله تشکیل شده است: Git جد مشترک (merge base) شاخه فعلی و مقصد را تعیین میکند، سپس هر commit از شاخه فعلی را به ترتیب روی شاخه مقصد اعمال میکند. اگر در هر مرحله تعارضی رخ دهد — rebase متوقف میشود و منتظر حل آن میماند.
# وضعیت اولیه: feature از develop 3 commit عقب است
git checkout feature/new-login
git rebase develop
# Git 3 commit از feature میگیرد و آنها را روی develop اعمال میکند
# اگر تعارضی نباشد — rebase خودکار تمام میشود
# اگر باشد — Git روی commit مشکلدار متوقف میشود
پس از rebase، شاخه feature شامل تمام commitهای develop به اضافه commitهای خودش است که به نظر میرسد ادامه develop هستند. این امکان را فراهم میکند که بدون ایجاد commit ادغام، از طریق fast-forward در develop ادغام شود.
مثال دقیق: توسعهدهنده یک شاخه feature از develop ایجاد کرد، دو commit انجام داد و در این مدت سایر توسعهدهندگان سه commit به develop اضافه کردند. Rebase دو commit feature را به مکان جدید منتقل میکند و کپیهایی با SHA جدید ایجاد میکند.
# 1. ایجاد شاخه feature
git checkout -b feature/payment-refactor develop
# 2. انجام commit در 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 روی commit مشکلدار متوقف میشود. توسعهدهنده تعارض را حل میکند، git add انجام میدهد و git rebase --continue را اجرا میکند. اگر نیاز به رد شدن از commit است — git rebase --skip، اگر لغو کل rebase — git rebase --abort.
پرچم --empty رفتار rebase را در commitهای خالی کنترل میکند — شرایطی که تمام تغییرات commit قبلاً در شاخه مقصد وجود دارد. به طور پیشفرض rebase متوقف میشود و درخواست تصمیم میکند. با پرچم --empty=drop، Git به طور خودکار چنین commitهایی را بدون توقف رد میکند که بازنشانی انبوه با تعداد زیادی commit را سرعت میبخشد.
Interactive rebase (git rebase -i) — ابزاری قدرتمند برای ویرایش تاریخچه commitها. این ابزار یک ویرایشگر با لیست commitها و دستورات کلیدی باز میکند: pick (نگهداشتن)، reword (تغییر پیام)، edit (تغییر محتوا)، squash (ترکیب با قبلی)، fixup (ترکیب بدون پیام)، drop (حذف).
# rebase تعاملی 4 commit آخر
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
نتیجه: سه commit (صفحه ورود، اعتبارسنجی، چیدمان) در یکی فشرده شدند و commit با توضیحات حذف شد. این امکان را فراهم میکند که یک تاریخچه تمیز بدون پیشنویس و اصلاحات برای بازبینی کد ارائه دهید. Interactive rebase ابزار استاندارد آمادهسازی شاخه feature قبل از Pull Request است.
Rebase و Merge یک وظیفه — ادغام تغییرات — را حل میکنند، اما به روشهای اساساً متفاوت. انتخاب بین آنها بستگی به این دارد که چه نوع تاریخچهای را میخواهید در git log ببینید و چه کسی دیگری با شاخه شما کار میکند.
| معیار | Merge | Rebase |
|---|---|---|
| تاریخچه | انشعاب را حفظ میکند | خطی، بدون شاخه |
| commit ادغام | ایجاد میشود (به جز ff) | ایجاد نمیشود |
| SHA commitها | تغییر نمیکنند | جدید ایجاد میشوند |
| ایمنی | برای شاخههای عمومی ایمن | خطرناک — تاریخچه را بازنویسی میکند |
| خوانایی لاگ | گراف انشعاب | خط مستقیم |
| git bisect | راحت — نقطه ادغام قابل مشاهده است | راحت — دنباله خطی |
قاعده عملی: برای ادغام در شاخههای مشترک (develop، main) از merge و برای بهروزرسانی شاخههای شخصی feature به وضعیت فعلی از rebase استفاده کنید. بسیاری از تیمها ترکیب میکنند: rebase feature روی develop، سپس --no-ff merge به develop.
Git bisect — ابزاری برای یافتن commitی که باعث پسرفت شده است. هنگام استفاده از merge، git bisect به درستی از commitهای ادغام با در نظر گرفتن هر دو والد عبور میکند. در rebase، bisect سریعتر کار میکند زیرا تاریخچه خطی است و نیازی به انشعاب ندارد. اما اگر rebase پس از آنکه commitها برای تیم شناخته شدند انجام شده باشد، SHAهای اصلی از بین میروند و bisect ممکن است commit مشکلدار را پیدا نکند.
Rebase در سه سناریو بهینه است: آمادهسازی شاخه feature برای Pull Request، بهروزرسانی شاخه شخصی به وضعیت فعلی main/develop و تمیز کردن تاریخچه قبل از ادغام. در هر مورد، rebase خوانایی تاریخچه را بدون خطر برای کار تیمی بهبود میبخشد.
قبل از Pull Request توصیه میشود interactive rebase را انجام دهید تا commitهای کاری (WIP، اصلاحات پس از بازبینی) را در واحدهای منطقی معنادار ترکیب کنید. این کار بازبینی کد را آسانتر میکند: بازبین به جای 15 commit کوچک، 3-5 تغییر ساختاریافته با پیامهای قابل فهم میبیند.
برای بهروزرسانی شاخه feature، rebase بر merge ترجیح داده میشود زیرا commitهای ادغام اضافی ایجاد نمیکند. اگر به طور دورهای git rebase develop را در شاخه feature انجام دهید، پس از ادغام نهایی آبشاری از 10 commit ادغام وجود نخواهد داشت — فقط commitهای تمیز feature روی develop.
تمیز کردن تاریخچه از طریق interactive rebase قبل از ادغام به شما امکان میدهد اصلاحات جزئی (غلط املایی، قالببندی) را پنهان کنید و commitها را بر اساس عملکرد گروهبندی کنید. پیامهای Git باید طبق قرارداد Conventional Commits (fix:، feat:، refactor:، docs:) باشند که changelog خودکار تولید میکند.
Rebase — عملیات خطرناکی است اگر نادرست اعمال شود. ریسک اصلی — بازنویسی تاریخچه منتشر شده. اگر توسعهدهنده شاخهای را که دیگران قبلاً push کرده و استفاده میکنند rebase کند، نسخههای محلی آنها از همگامسازی خارج میشوند و مجبور به انجام force-pull با خطر از دست دادن دادهها میشوند.
برای به حداقل رساندن ریسکها، قانون زیر را رعایت کنید: rebase فقط برای شاخههای شخصی که منتشر نشدهاند. اگر شاخه قبلاً در مخزن مشترک است — از merge با --no-ff استفاده کنید. در صورت نیاز به rebase شاخه منتشر شده — تیم را مطلع کنید و force push را از قبل هماهنگ کنید.
حفاظت خودکار در برابر rebase خطرناک از طریق server-side hooks پیادهسازی میشود: pre-receive hook در سمت سرور Git میتواند بررسی کند که آیا push commitهای منتشر شده را بازنویسی میکند. GitHub و GitLab حفاظت داخلی برای شاخههای محافظت شده ارائه میدهند — force push مسدود میشود مگر اینکه حفاظت توسط مدیر لغو شود.
سوالات متداول
تاریخچه شاخه تغییر میکند — SHA commitها متفاوت میشوند. هر کسی که قبلاً این شاخه را push کرده یا شاخههای فرزند از آن ایجاد کرده است، هنگام git pull با تعارضات مواجه میشود. بازیابی نیاز به مداخله دستی دارد و میتواند منجر به از دست دادن commitها شود.
قبل از اتمام — git rebase --abort. پس از اتمام — فقط از طریق git reflog، اگر rebase اخیراً انجام شده باشد. reflog تاریخچه جابجاییهای HEAD را ذخیره میکند که با آن میتوان به وضعیت قبل از rebase بازگشت: git reset --hard HEAD@{1}.
Rebase دنباله commitها را به پایه جدید منتقل میکند. Cherry-pick یک یا چند commit خاص را در شاخه فعلی اعمال میکند. Rebase برای کل زنجیره خودکار است، cherry-pick — انتخاب دستی هر commit.
توصیه میشود، اما اجباری نیست. Rebase قبل از PR شاخه را به وضعیت فعلی main/develop بهروز میکند و تاریخچه را تمیز میکند. اگر شاخه اخیراً ایجاد شده و نیازی به بهروزرسانی ندارد — interactive rebase برای تمیز کردن commitها کافی است.
برچسبها در rebase جابجا نمیشوند. اگر روی commitی که rebase شده است برچسبی وجود داشت، این برچسب روی commit قدیمی که اکنون در تاریخچه شاخه نیست باقی میماند. توصیه میشود commitهای شاخههای feature را برچسبگذاری نکنید، فقط در main.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید