گیت ابزاریه که برنامه نویس ها (و اخیرا خیلی های دیگه مثل گرافیست ها و ...) برای داشتن کنترل روی ورژن های نرم افزار و کار تیمی ازش استفاده میکنن. هر کسی تو شروع دستور های ساده ای مثل `push` و `pull` و کاربردشون رو یاد میگیره. ولی گیت از اون ابزار هاییه که عمق اش ته نداره و راهی جز تجربه کردن هم برای یاد گیری عمیق اش نیست. نکته مثبت اینه که اگر حواستون باشه تقریبا هیچ ریسکی وجود نداره و کافیه هر وقت کار تستی ای میخواین انجام بدین اون رو روی یه برنچ جدا از برنچی که روش کار میکنین اعمال کنین و در نهایت خیلی راحت به وضعیت قبلی که روش کار میکردین برگردین.
اگر با rebase آشنا نیستید اول داکیومنت سرراستش رو بخونید.
برای من rebase از جمله قابلیت های گیت بود که من مدت ها بدون استفاده ازش کارم رو پیش بردم و کمبود خاصی هم حس نمیکردم. بعد از این که یکی منو باهاش آشنا کرد و سعی کردم یادش بگیرم احساس کردم که خودم و پروژه هام رو از داشتن یه history تمیز و عالی محروم کردم و شروع کردم به squash کردن commit ها و گذاشتن `--rebase` آخر خیلی از pull هام از برنچ اصلی و همچنین استفاده از rebase به جای merge تا جایی که به conflict های عجیب نمیخوردم، گاهی هم که مشکلی پیش میومد بر میگشتم به همون سیستم merge سابق و تقریبا مشکلی هم نبود. مشکل اصلی از جایی شروع شد که بقیه بچه های تیم رو هم برای داشتن history تمیز روی برنچ اصلی تشویق به استفاده از rebase کردم. چندین بار با مشکلی مواجه شدیم به این شکل که بچه ها میخواستن روی feature branch خودشون push کنن و با این پیغام مواجه میشدن:
error: failed to push some refs to 'https://github.com/...' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again.
در حالی که هیچ کس جز اون ها روی اون برنچ کار نمیکرد و قاعدتا نباید همچین مشکلی بوجود میومد. بعد از این من سعی کردم مفهوم rebase رو درست یاد بگیرم تا علت مشکل رو بفهمم. کلیت چیزی هم که دستگیرم شد این بود:
وقتی rebase میکنیم، گیت کامیت های برنچی که با اون rebase کردیم رو میاره پشت سر کامیت های برنچ ما قرار میده (از جایی که برنچ ما جدا شده) و کامیت های ما در انتهای اون قرار میده. تا اینجا مشکلی نیست، تنها نکته اینه که کامیت های ما که در انتها قرار میگیرن، از نظر message و description و ... کاملا با کامیت های قبلی یکی هستند ولی sha متفاوتی دارن. یعنی وقتی مجدد روی branch خودمون push میکنیم روی remote کامیت های متفاوتی وجود داره و به همین دلیل بدون force کردن امکان push وجود نداره.
حالا میرسیم به سوال اصلی و اینکه کی rebase کنیم و کی نه. نظر من به طور خلاصه اینه:
با استفاده به جا از rebase میشه history تمیز تری داشت و استفاده بدش باعث تلف کردن وقت و حتی کثیف و ناخوانا شدن history میشه.
اینو همیشه یادتون باشه:
کامیتی که بعد rebase ایجاد میشه تقریبا همون commit قبلیه!
خوشحال میشم تجربه های خودتون رو هم در این مورد و سایر کارهای جالبی که با گیت میشه کرد اینجا بگین.