همه چیز در مورد برطرف کردن Merge conflict در Git



visibility  
mode_comment   ۲

همه چیز در مورد برطرف کردن Merge conflict در Git

در این مطلب میخوایم در مورد Merge conflict صحبت کنیم و ببینیم که چطور میتونیم Merge conflict ها رو برطرف کنیم.

فرض کنید که بصورت تیمی بر روی یک پروژه کار میکنید. همکارتون تغییراتی رو بر روی یک فایل به وجود آورده و اون رو به Remote ارسال یا Push کرده است. شما هم در همین لحظه در Local خودتون همون خط از فایل رو تغییر دادید و از تغییرات همکارتون خبری ندارید.

بعد از مدتی همکارتون از شما درخواست میکنه که اطلاعات جدید رو Pull کنید و شما هم دستور git pull رو اجرا میکنید تا آخرین تغییرات دانلود بشه و پروژه به روز بشه. در این لحظه هست که یک Merge conflict به وجود میاد و Git گیج میشه و نمیدونه که تغییراتی که در Local شما وجود داره رو باید نگه داره و یا تغییراتی که همکارتون بر روی خط مورد نظر انجام داده است.

این مشکل حتما در پروژه‌های تیمی پیش نمیاد و اگر بر روی چند Branch هم کار کنید، گاهی به این مشکل برخواهید خورد و باید برطرف کردن اون رو بلد باشید و یک نیاز اساسی به حساب میاد. مثلا فرض کنید که یک فایل رو در دو Branch تغییر دادید و حالا میخواید این دو Branch رو با هم Merge یا ادغام کنید. در این مواقع هم به Merge conflict خواهید خورد.

خب اول بیایم یک Merge conflict رو به وجود بیاریم تا ببینیم که چطور میتونیم اون رو برطرف کنیم.

یک پوشه بنام merge-conflict در desktop به وجود میارم و در Command line دستور git init رو اجرا میکنم تا بتونم از git در این پوشه استفاده کنم. حالا یک فایل بنام sample.txt میسازم و یک متن ساده رو درون اون قرار میدم و اون رو add و commit میکنم. متن مورد نظر بصورت زیر هست:

متن commit هم first commit قرار میدم تا مشخص باشه. خب حالا یک branch دیگه از روی این branch به وجود میارم و اسم اون رو second-edition قرار میدم. بصورت زیر:

خب در اینجا متن فایل sample.txt رو بصورت زیر تغییر میدم:

خب این تغییر رو با پیام second commit ثبت میکنم.

خب حالا فرض کنید که به دلیلی مجبور هستید به branch قبلی برگردید و تغییراتی رو در اون انجام بدین. برای اینکار git checkout master رو اجرا میکنیم تا وارد شاخه master بشیم. در اینجا متن فایل sample.txt رو بصورت زیر تغییر میدیم:

این تغییر رو با پیام third commit ثبت میکنیم. پس تا حالا 2 commit در شاخه master داریم و یک commit هم بنام second commit در شاخه feature/second-edition داریم.

حالا بعد از مدتی میخوایم شاخه feature/second-edition رو با شاخه master ادغام یا merge کنیم. برای اینکار در شاخه master دستور git merge feature/second-edition رو اجرا میکنیم. خروجی بصورت زیر میشه:

همونطور که مشاهده میکنید بعد از اجرا کردن این دستور، git تلاش میکنه که بصورت اتوماتیک تغییرات sample.txt رو ادغام یا merge کنه. ولی بخاطر اینکه هم در شاخه master و هم در شاخه feature/second-edition تغییراتی بر روی یک خط از یک فایل داده شده است، git نمیدونه کدوم مورد رو در نظر بگیره و به همین دلیل merge بصورت کامل انجام نمیشه.

در اینجا هست که وارد حالت MERGING میشیم و به همین دلیل هم شاخه master به master|MERGING تبدیل میشه و به این معنی هست که شما باید conflict ها رو برطرف کنید و مجددا commit رو اجرا کنید.

متخصص وردپرس
قالب ها و پلاگین های حرفه ای وردپرس رو خودت بنویس! بازار طراحی قالب و پلاگین نویسی وردپرس به شدت داغه و اگر بلد باشید با برنامه نویسی اختصاصی، قالب ها و پلاگین های دلخواه بنویسید تو مارکت های مطرح دنیا و یا از طریق فریلنسری می تونید به درآمد بالا برید. دوره متخصص وردپرس سون لرن رو حتما ببینید: متخصص وردپرس arrow_back

زمانی که در حالت MERGING هستید، اگر فایل Sample.txt رو باز کنید، چنین محتوایی در اون قرار گرفته است:

کدهایی که بین خط <<<<<< HEAD و ======= هست، کدهایی هستند که در شاخه فعلی یا master وجود دارد و کدهایی که بین ======= و >>>>>>> feature/second-edition وجود دارد، کدهایی هستند که در شاخه feature/second-edition قرار داشته‌اند. این دو خط همان دو خطی هستند که conflict برای اونا رخ داده است.

شما باید بین این دو کد یکی رو انتخاب کنید و دیگری رو بصورت دستی حذف کنید. همچنین میتونین بسته به شرایط پروژتون، هر دو مورد رو حذف یا هر دو مورد رو نگه دارید. اگر شما از ویرایشگر Visual studio code استفاده میکنید، زمانی که merge conflict رخ میده، کدها بصورت زیر میشن:

میبینید که با استفاده از رنگهای متفاوت مشخص میکنه که دو چیزی که conflict بر روی اونا رخ داده است، چه چیزهایی هستند. حالا در بالای این کدها، لینکهایی قرار داده شده که میتونین با استفاده از اونا به راحتی merge conflict رو برطرف کرده و بین این دو کد اونی که مدنظرتون هست رو انتخاب کنید.

  • Accept current change : با انتخاب این گزینه اون تغییری که در شاخه master یا فعلی هست، انتخاب میشه.
  • Accept incoming change : با انتخاب این گزینه اون تغییری که در شاخه feature/second-edition هست، انتخاب میشه.
  • Accept both changes : با انتخاب این گزینه، هر دو تغییر بصورت همزمان نگه داشته میشن.
  • اگر هیچکدام از موارد رو نخواستید، میتونین به راحتی از خط 1 تا خط 5 رو بصورت کامل حذف کنید. با این کار هم merge conflict برطرف میشه.

خب فرض کنید که من بر روی Accept incoming change کلیک میکنم. با اینکار محتوای فایل sample.txt بصورت زیر میشه:

خب تا اینجا merge conflict رو برطرف کردیم و حالا اگر merge conflict دیگری هم وجود داشته باشه، باید اونا رو هم به همین صورت برطرف کنیم. زمانی که همه merge conflict ها رو برطرف کردید، باید دستور git commit رو اجرا کنید تا تغییرات مورد نظر انجام بشه و merge بصورت کامل انجام بشه و از حالت MERGING خارج بشیم.

با این کار ادیتور پیش فرض برای git باز میشه و متن commit که از قبل وجود داشته در اون قرار داده شده است.

ادیتور پیش فرض من از مدل vim هست و مال شما میتونه هر چیز دیگه‌ای باشه. در حالت بالا میتونین متن commit رو تغییر بدین و یا بدون تغییر اون رو ثبت کنید. من میخوام همین متن رو قرار بدم و بنابراین هیچ تغییری در اون نمیدم و 😡 رو میزنم تا از ویرایشگر خارج بشم. با اینکار commit مورد نظر با این متن ثبت میشه و merge با موفقیت به پایان میرسه:

همونطور که میبینید از حالت MERGING هم خارج شده‌ایم.

در این لینک آموزش داده شده که چطور میتونین ادیتور پیش فرض git رو تغییر بدین و اون رو مثلا vscode یا sublime text یا ... قرار بدین.

همچنین شما میتونین بجای استفاده از git commit  از git commit -m "message" استفاده کنید. با اینکار متن رو بصورت مستقیم انتخاب کرده‌اید و دیگه ادیتور پیش فرض باز نمیشه و merge با موفقیت انجام میشه.

حالت merge conflict در زمانی که git pull هم میکنید میتونه رخ بده. وقتی که دستور git pull رو اجرا میکنید، در ابتدا تغییرات داده شده از Remote دانلود میشه و بعد از اون git سعی میکنه که بصورت اتوماتیک این تغییرات رو با کدهای local شما ادغام یا merge کنه. بنابراین اگر مانند توضیحات بالا، یک فایل وجود داشته باشه که برای یک خط اون دو تغییر در نظر گرفته شده باشه، باز هم به merge conflict برمی‌خوریم.

نتیجه گیری

در این مطلب یاد گرفتیم که چطور merge conflict هایی که در زمان git merge یا git pull ممکن هست رخ بده رو به راحتی برطرف کنیم و merge رو با موفقیت به پایان برسونیم.

شما میتونین در این لینک از وبسایت سون لرن مطالب دیگری که مربوط به موضوع git هست رو مطالعه کنید و چیزهای بیشتری در مورد اون یاد بگیرید.

comment دیدگاه کاربران
سما عبدی

آموزشی کامل و واضح بود ممنون استفاده کردیم

محمد اسفندیاری

خواهش میکنم
موفق باشید

نیاز به لاگین

برای ارسال دیدگاه و یا پرسیدن سوال خود در این قسمت، باید در سایت لاگین شوید.