ویرگول
ورودثبت نام
Ali Fazeli
Ali Fazeliمهندس نرم افزار
Ali Fazeli
Ali Fazeli
خواندن ۳ دقیقه·۷ سال پیش

چه موقع از قابلیت rebase توی git استفاده کنیم؟

گیت ابزاریه که برنامه نویس ها (و اخیرا خیلی‌ های دیگه مثل گرافیست ها و ...) برای داشتن کنترل روی ورژن های نرم افزار و کار تیمی ازش استفاده می‌کنن. هر کسی تو شروع دستور های ساده ای مثل `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 کنیم و کی نه. نظر من به طور خلاصه اینه:‌

  • ‌ ‌‌‌‌‌‌‌‌‌‌‌‌‌وقتی برنچی که روش کار می‌کنیم رو هنوز push نکردیم و می‌خوایم آپدیتش کنیم با کار بقیه. با این کار از شر کامیت های merge اضافی روی history که به خاطر pull کردن کار بقیه ایجاد می‌شن راحت می‌شیم.
  • اگر برنچ رو پوش کردیم و مطمئنیم اون برنچ روی هیچ برنچی روی remote تا حالا merge نشده می‌تونیم همچنان rebase کنیم، ولی باید حواسمون باشه که به دلیل متفاوت بودن commit sha باید force push کنیم وگرنه با همون خطا مواجه می‌شیم.
  • اگر برنچ روی remote وجود داره و داخل branch های دیگه merge شده هیچ وقت نباید rebase کنیم.
  • روی برنچ هایی که افراد مختلف ازش استفاده می‌کنن هم نباید rebase انجام شه.

با استفاده به جا از rebase می‌شه history تمیز تری داشت و استفاده بدش باعث تلف کردن وقت و حتی کثیف و ناخوانا شدن history میشه.

اینو همیشه یادتون باشه:

کامیتی که بعد rebase ایجاد می‌شه تقریبا همون commit قبلیه!


خوشحال می‌شم تجربه های خودتون رو هم در این مورد و سایر کارهای جالبی که با گیت می‌شه کرد اینجا بگین.

gitگیتتوسعه نرم افزارنرم افزار
۲۵
۲
Ali Fazeli
Ali Fazeli
مهندس نرم افزار
شاید از این پست‌ها خوشتان بیاید