چطور تعارض (Conflict) در Merge گیت را حل کنیم
آموزش

چطور تعارض (Conflict) در Merge گیت را حل کنیم

merge با CONFLICT متوقف شده و نمی‌دانید از کجا شروع کنید؟ یک تعارض واقعی را قدم‌به‌قدم حل می‌کنیم، از خواندن علامت‌ها تا کامیت امن و راه برگشت همیشه‌باز

تحریریه‌ی دینا کد
نویسنده
۳ دقیقه مطالعه۳ بازدید
اشتراک گذاری۳
فهرست مطالب
  1. ۱یک تعارض واقعی
  2. ۲فایل الان چه شکلی است
  3. ۳حل‌کردن یعنی همین سه خط را پاک کنید
  4. ۴اگر وسط راه پشیمان شدید
  5. ۵چند فایل تعارض دارند؟
  6. ۶اگر می‌دانید کدام نسخه باید کامل برنده شود

وقتی git merge با خط CONFLICT (content): Merge conflict in ... می‌ایستد، فایل خراب نشده؛ گیت فقط نتوانسته خودش تصمیم بگیرد و انتخاب را به شما سپرده. فایل را باز کنید، بین دو نسخه انتخاب کنید، علامت‌ها را پاک کنید و بعد git add و git commit بزنید. در ادامه همین کار را روی یک تعارض واقعی قدم‌به‌قدم انجام می‌دهیم.

یک تعارض واقعی

دو شاخه، هر دو یک خط را جور دیگری عوض کرده‌اند:

bash$ git merge feature-a
Auto-merging config.yml
CONFLICT (content): Merge conflict in config.yml
Automatic merge failed; fix conflicts and then commit the result.

فایل الان چه شکلی است

yaml<<<<<<< HEAD
version: 1.5
=======
version: 2.0
>>>>>>> feature-a
name: shop

بین <<<<<<< HEAD و ======= نسخه‌ی شاخه‌ی فعلی شماست؛ بین ======= و >>>>>>> feature-a نسخه‌ی شاخه‌ای که دارید merge می‌کنید. git status --porcelain هم همین وضعیت را با کد UU (Unmerged, both modified) نشان می‌دهد.

حل‌کردن یعنی همین سه خط را پاک کنید

تصمیم بگیرید کدام نسخه درست است، یا حتی یک نسخه‌ی سوم بنویسید، و هر سه خط علامت را حذف کنید:

yamlversion: 2.0
name: shop
bashgit add config.yml
git commit --no-edit

بدون -m، گیت یک پیام آماده می‌گذارد: Merge branch 'feature-a'. کامیت نهایی دو والد دارد؛ یکی آخرین کامیت شاخه‌ی خودتان و دیگری آخرین کامیت شاخه‌ی merge‌شده. در git log --graph هم همین ساختار به شکل آن الماس آشنا دیده می‌شود.

اگر وسط راه پشیمان شدید

bashgit merge --abort

فایل‌ها را دقیقاً به حالت قبل از شروع merge برمی‌گرداند؛ انگار هیچ‌وقت merge نزده بودید. تا وقتی commit نهایی را نزده‌اید، این دستور همیشه در دسترس است؛ نگران خراب‌کردن چیزی نباشید.

چند فایل تعارض دارند؟

bashgit status --porcelain | grep '^UU'

هر خطی که با UU شروع شود، هنوز حل نشده. تا این لیست خالی نشود، git commit اصلاً اجازه نمی‌دهد.

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

گاهی ادیت دستی لازم ندارید و می‌خواهید یک طرف کامل جای‌گزین شود:

bashgit checkout --theirs config.yml   # نسخه‌ی شاخه‌ای که merge می‌کنید
git checkout --ours config.yml     # نسخه‌ی شاخه‌ی خودتان
git add config.yml

روی همان تعارض بالا، --theirs نسخه‌ی feature-a (یعنی version: 2.0) را بدون باز کردن فایل و پاک‌کردن علامت‌ها کامل جای‌گزین کرد. برای فایل‌های باینری (مثلاً یک تصویر) که ادیت دستی ندارند، این تنها راه است.

اگر تازه‌کارید و هنوز شاخه‌زدن، pull request و حل تعارض روی پروژه‌ی واقعی را تمرین نکرده‌اید، دوره‌ی گیت و گیت‌هاب دقیقاً همین سناریو را چند بار زیر دستتان تمرین می‌دهد.

تحریریه‌ی دینا کد
نویسنده

نظرها

اولین نفری باشید که نظر می‌دهد
برای ثبت نظر وارد شوید

سؤالتان را بپرسید یا تجربه‌تان را بنویسید تا نویسنده‌ی مطلب پاسخ بدهد.

مطالب مرتبط

از همین دسته
دستور stash در گیت چیست و چه کاربردی دارد
آموزش

دستور stash در گیت چیست و چه کاربردی دارد

دستور stash در گیت تغییرات ثبت‌نشده شاخه کاری را موقتا کنار می‌گذارد تا بدون ثبت کامیت ناقص بتوانید روی وظایف فوری کار کنید.

تحریریه‌ی دینا کد۶ دقیقه
diff در گیت چیست و چه‌وقت استفاده می‌شود؟
آموزش

diff در گیت چیست و چه‌وقت استفاده می‌شود؟

git diff دو نسخه از کدها را کنار هم می‌گذارد و خط‌به‌خط نشان می‌دهد چه چیزی عوض شده. یک نگاه به diff قبل از هر add و commit کافی است

تحریریه‌ی دینا کد۷ دقیقه