برنامه نویسی

سمت تاریک ادغام git

تغییر پایه و ادغام

هنگامی که صحبت از مدیریت تغییرات در یک مخزن Git می شود، دو مورد از رایج ترین دستورات مورد استفاده هستند git merge و git rebase. اینها هستند دو راه برای حل یک مشکل – ادغام تغییرات از یک شاخه به شاخه دیگر.

در حالی که هر دو دستور برای ترکیب تغییرات استفاده می‌شوند، اما به روش‌های متفاوتی کار می‌کنند و می‌توانند اثرات متفاوتی بر تاریخچه مخزن داشته باشند.

درک تفاوت‌های بین git merge و git rebase می‌تواند به شما کمک کند دستور مناسب برای گردش کار خود را انتخاب کنید و از درگیری‌ها و عوارض احتمالی جلوگیری کنید.

ساده ترین مثال – ادغام سریع به جلو

فرض کنید یک شاخه ویژگی دارید feature ایجاد شده از master شاخه، و وجود داشت بدون تغییر جدید در master شاخه از زمان ایجاد feature.

$ git init
# ...
$ git commit -m "A1"
$ git switch -c feature
# ... 
$ git commit -m "B1" 
# the same with B2 and B3
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شاخه های فعال در git repository

در آن صورت، الف ادغام سریع به جلو می توان برای ادغام تغییرات در feature به master. نتیجه یک تاریخچه خطی با تمام تغییرات از feature در بالای master، و هیچ تعهد ادغام جدیدی ایجاد نخواهد شد.

$ git switch master
$ git merge feature

Updating 9505fd5.-ae9636f
Fast-forward
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شاخه های فعال در git repository

همه ادغام ها سریع به جلو نیستند!

این را تصور کنید: شما سخت روی یک ویژگی جدید برای پروژه خود کار کرده اید و تقریباً به پایان رسیده اید. شما تمام تغییرات خود را در یک شاخه جداگانه انجام داده اید، بنابراین تو با استاد دخالت نمیکنی شاخه.

شاخه های فعال در git repository

با این حال، درست زمانی که می خواهید همه چیز را جمع بندی کنید، متوجه می شوید شخص دیگری ویژگی جدید خود را ادغام کرده است بدون اینکه به شما بگویم وارد شعبه اصلی شوید.

شاخه های فعال در git repository

حالا شما مشکل دارید.

شما نمی توان به سادگی تغییرات شما را ادغام کرد به master با ادغام سریع رو به جلو، زیرا شاخه اصلی دارد تغییر کرد از زمانی که شاخه ویژگی خود را ایجاد کردید.

در عوض، باید از a استفاده کنید ادغام غیر سریع به جلو، که یک تعهد ادغام جدید ایجاد می کند و در صورت همپوشانی تغییرات شما با ویژگی دیگری که در Master ادغام شده است، به طور بالقوه باعث تداخل می شود.

$ git switch master
$ git merge feature

Merge branch 'feature'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شاخه های فعال در git repository

توجه به این نکته ضروری است ادغام های Git متمرکز بر جلو هستند، یعنی آنها تاریخ موجود را تغییر ندهید به هر طریقی هنگامی که دو شاخه را ادغام می کنید، Git یک commit جدید ایجاد می کند که شامل تغییرات هر دو شاخه می شود، اما commit های موجود در هر شاخه دست نخورده باقی می مانند.

این بدان معنی است که اگر در حین ادغام اشتباه کردید، همیشه می توانید به کامیت های اصلی برگردید و از نو شروع کن

همچنین به این معنی است که می توانید یک شاخه را چندین بار ادغام کنید بدون تغییر تعهدات موجود.

مشکلات ادغام

اگر روی شاخه ویژگی کار می کنید در حالی که سایر اعضای تیم تغییرات را به شاخه اصلی فشار می دهند، مهم است که شعبه خود را با این تغییرات به روز نگه دارید.

یکی از راه‌های انجام این کار این است که شاخه اصلی را در شاخه ویژگی خود ادغام کنید، که می‌تواند منجر به چندین تعهد ادغام و تاریخچه ارتکاب به‌هم ریختگی شود.

ادغام چندین بار شاخه اصلی در شاخه ویژگی می تواند منجر به تعداد قابل توجهی ادغام شود که می تواند پیگیری و درک تاریخچه Git شما را دشوار کند.

شاخه های فعال در git repository

$ git checkout feature
$ git merge master
# done multiple times to have feature branch updated
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شاخه های فعال در git repository
شاخه های فعال در git repository

در نتیجه، در نظر گرفتن استراتژی های جایگزین، مانند تغییر پایه یا له کردن متعهد می شود که شما را حفظ کند commit history clean و سازماندهی شده در حالی که هنوز تغییرات از شاخه اصلی را در بر می گیرد.

Rebasing یک گزینه دیگر است

یک جایگزین برای ادغام، تغییر شاخه ویژگی خود به شاخه اصلی است.

طبق مستندات Git، git rebase دستوری است که برای اعمال تغییرات از یک شاخه به شاخه دیگر استفاده می شود. ایده اصلی این است که تغییراتی را که در یک شاخه ایجاد شده است (به نام شاخه “منبع”) و دوباره آنها را در بالای شاخه دیگر (به نام شاخه “هدف”) پخش کنید. این می تواند زمانی مفید باشد که بخواهید تغییرات ایجاد شده در یک شاخه را در شاخه دیگر، در حالی که a را حفظ کنید، ترکیب کنید تاریخچه پاک و خطی.

را git rebase دستور با یافتن commit جد مشترک دو شاخه (یعنی نقطه ای که در آن از هم جدا شده اند) کار می کند و سپس یک سری commit جدید ایجاد می کند که تغییرات ایجاد شده در شاخه منبع را در بالای شاخه هدف اعمال می کند. فرآیند شامل مراحل زیر است:

  1. Git تعهد اجداد مشترک دو شاخه را مشخص می کند.
  2. Git یک شاخه موقت جدید بر اساس شاخه هدف ایجاد می کند.
  3. Git تغییرات ایجاد شده در شاخه منبع را یکی یکی به ترتیبی که در ابتدا ایجاد شده اند اعمال می کند.
  4. Git برای هر یک از تغییرات commit های جدیدی ایجاد می کند و آنها را در شاخه موقت اعمال می کند.
  5. در نهایت، Git نشانگر شاخه هدف را به commit های جدید منتقل می کند، و به طور موثر تغییرات را از شاخه مبدا ترکیب می کند.

شایان ذکر است که در طول این فرآیند، در صورتی که تغییرات یکسانی در هر دو شاخه مبدا و هدف ایجاد شود، ممکن است تداخل ایجاد شود. در این موارد، Git فرآیند rebase را متوقف می‌کند و به شما اجازه می‌دهد تا قبل از ادامه، تضادها را به صورت دستی حل کنید.

ولی…

… یک پتانسیل عیب استفاده از git rebase این است که آن را تاریخ را بازنویسی می کند با حرکت دادن کل شاخه ویژگی برای شروع از نوک شاخه اصلی، که منجر به ایجاد commit های جدید برای هر یک از commit های شاخه ویژگی اصلی می شود.

در حالی که این رویکرد می تواند commit های ادغام را حذف کند و تاریخچه commit را خطی نگه دارد، همچنین می تواند ردیابی تغییرات را دشوار می کند در طول زمان و اگر سایر اعضای تیم در همان شاخه کار کنند، به طور بالقوه باعث درگیری می شود.

$ git switch feature
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شاخه های فعال در git repository

$ git rebase master
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

شاخه های فعال در git repository

⛔️ هشدار ⛔️

مهم است که از تغییر پایه تعهداتی که با سایر اعضای تیم به اشتراک گذاشته شده است خودداری کنید.

اگر قبلاً commit‌ها را به یک مخزن مشترک فشار داده‌اید، معمولاً توصیه نمی‌شود که تاریخچه را با تغییر پایه آن commit‌ها بازنویسی کنید، زیرا انجام این کار می‌تواند درگیری ایجاد می کند و درک و پیگیری تغییرات را برای سایر اعضای تیم دشوار می کند.

نتیجه

ادغام

طرفداران

  • تاریخچه کاملا قابل ردیابی،
  • مبتدی دوستانه،
  • زمینه اصلی شاخه منبع را حفظ می کند،
  • commit های مربوط به شاخه منبع از سایر تعهدات شاخه جدا می شوند

⛔️ منفی

  • تاریخ می تواند به شدت توسط بسیاری از ادغام ها آلوده شود

Rebasing

طرفداران

  • تاریخچه کد ساده، خطی و قابل خواندن
  • دستکاری یک تاریخچه commit ساده تر از تاریخچه بسیاری از شاخه های ویژگی جداگانه با commit های اضافی است

⛔️ منفی

  • کاهش این ویژگی به تعداد انگشت شماری از commit ها می تواند زمینه را پنهان کند
  • هنگام استفاده از rebasing نسبت به هنگام ادغام نیاز به رسیدگی دقیق تری است
  • برای مقابله با تداخل ها به کار بیشتری نیاز است، زیرا تداخل های مشابه باید بارها و بارها حل شوند تا شاخه ویژگی به روز شود، و تداخل ها باید به ترتیبی که برای ادامه بازنمود ایجاد شده اند حل شوند.

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

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا