جواب کوتاه: روی شاخهای که هنوز push نکردهاید یا کسی دیگر رویش کار نمیکند، rebase بزنید تا تاریخچه صاف بماند؛ روی شاخهای که با بقیه مشترک است، فقط merge بزنید. تفاوتشان در همین یک چیز است: rebase کامیتهای شما را دوباره میسازد؛ merge هیچ کامیتی را دست نمیزند.
یک تاریخچهی واقعی
دو شاخه از یک نقطه جدا شدهاند: main یک کامیت مستندات دارد، feature دو کامیت کد دارد.
bash$ git log --oneline --graph --all
* adf18c4 بهروزرسانی مستندات
| * 96ec6ca افزودن logout
| * 2f9bf5a افزودن login
|/
* 1d1e831 کامیت پایه
merge: هر دو تاریخچه کنار هم میمانند
bash$ git checkout feature
$ git merge main
* cbcd8a8 Merge branch 'main' into feature
|| * adf18c4 بهروزرسانی مستندات
* | 96ec6ca افزودن logout
* | 2f9bf5a افزودن login
|/
* 1d1e831 کامیت پایه
یک کامیت جدید (cbcd8a8) با دو والد ساخته شد. کامیتهای login و logout دقیقاً همان هش قبلی را دارند — هیچچیزی بازنویسی نشده، فقط یک نقطهی اتصال اضافه شده.
rebase: تاریخچه صاف میشود، ولی کامیتها عوض میشوند
bash$ git checkout feature
$ git rebase main
* 1045314 افزودن logout
* dca4a16 افزودن login
* 25505c8 بهروزرسانی مستندات
* 1d1e831 کامیت پایه
نتیجه یک خط راست است — انگار از اول روی main کار کرده بودید. ولی نگاه کنید به هشها: login از 2f9bf5a شد dca4a16، logout از 96ec6ca شد 1045314. اینها کامیتهای جدیداند با همان محتوا؛ کامیتهای قبلی دیگر روی این شاخه نیستند.
چرا همین تفاوت، قانونِ «rebase نزن روی شاخهی pushشده» را میسازد
چون هش عوض شده، اگر همین شاخه را قبلاً push کرده باشید، push دوبارهی معمولی رد میشود:
bash$ git push origin feature
error: failed to push some refs to '...'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart.
گیت فکر میکند شاخهی remote از شاخهی شما جلوتر است — چون کامیتهای قدیمی هنوز آنجا هستند و شما دارید یک تاریخچهی متفاوت با همان اسم میفرستید. تنها راه، push --force (یا امنترش، --force-with-lease) است — و اگر همکارتان همان کامیتهای قدیمی را pull کرده باشد، کارش روی تاریخچهای میماند که دیگر وجود ندارد.
قانون عملی
| وضعیت | انتخاب |
|---|---|
| شاخهی شخصی، هنوز push نشده | rebase — تاریخچهی تمیزتر |
| شاخهای که دیگران هم رویش کار میکنند | فقط merge |
| میخواهید commit-by-commit مرور کنید | rebase قبل از باز کردن PR |
| مطمئن نیستید کسی دیگر pull کرده یا نه | merge — همیشه امن است |
اگر مطمئن نیستید، merge بزنید. یک کامیت merge اضافه در تاریخچه، خیلی کمتر از یک تاریخچهی بازنویسیشده روی شاخهی مشترک هزینه دارد.
اگر میخواهید کار تیمی روی گیتهاب — شاخه، pull request، حل تعارض — را با پروژهی واقعی تمرین کنید، دورهی گیت و گیتهاب دقیقاً همین سناریوها را چند بار زیر دستتان میبرد.





نظرها
اولین نفری باشید که نظر میدهدسؤالتان را بپرسید یا تجربهتان را بنویسید — نویسندهی مطلب پاسخ میدهد.