رفع conflict در گیت

img
img
img
img
shape
shape
blog-details
16
فروردین
رفع conflict در گیت
نویسنده : محمدرضا لیایی
دسته بندی : آموزش گیت کنترلر
زمان مطالعه : 35 دقیقه

یکی از بزرگترین مشکلاتی که کاربران گیت همواره در اغلب پروژه ها با آن مواجه می شوند  conflict یا همان تداخل در کد های بین شاخه ای است که بر اثر فرآیند merging اتفاق می افتد. در این جلسه قصد داریم تا این مورد را بررسی کنیم و ببینیم چرا این مشکل به وجود می آید و به چه شکلی می توانیم این مشکل را حل کنیم.

با پروژه جلسه قبل شروع می کنیم و آن را ادامه می دهیم.

ایجاد conflict

در پروژه جلسه قبل در کنار شاخه master یک شاخه دیگر به نام development ایجاد کردیم. با وارد کردن دستور git status در ابتدا مطمئن می شویم که شاخه ها خالی است. سپس commit های موجود بر روی دو شاخه را چک می کنیم و مطمئن می شویم که مشکلی در این شاخه ها وجود نداشته باشد. بعد از اطمینان می خواهیم تغییراتی را ایجاد کنیم که باعث به وجود آمدن conflict در کد ها شود.
نکته: تداخل ها یا همان conflict ها اغلب در فایل ها با فرمت های مختلف به وجود می آیند در اینجا قصد داریم تا دو مورد از این تداخل ها که بسیار شایع هستند را ایجاد کرده و سپس حل کنیم تا اگر در پروژه های واقعی با این قبیل مشکل ها برخورد کردیم به راحتی آن را مرتفع کنیم.

مورد اول

ساده ترین حالت برای یک تداخل این است که یک مورد هم در شاخه اصلی master تغییر پیدا کند و هم در شاخه فرعی development. در این شرایط گیت قادر نیست تشخیص دهد که کدام یک از تغییرات را باید ذخیره کند به همین خاطر از شما سوال می کند که کدام تغییر مد نظر شماست ؟ در ادامه این تداخل را بررسی می کنیم.

با استفاده از ادیتور زبان برنامه نویسی خودتون ابتدا به شاخه master بروید. فایل aboutus.html را باز کنید. نوشته درون پاراگراف را از Lorem Ipsum به change on master branch تغییر دهید. کدهای html درون aboutus.html در کل به صورت زیر در می آید.

Aboutus.html
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <header>
        <h1>aboutus</h1>
    </header>
    <p>changes on development branch</p>
</body>
</html>

 سپس با استفاده از دستور git commit تغییرات را commit کنید. اگر با commit کردن آشنا نیستید می توانید به جلسه پنجم مراجعه کنید.

پیشنهاد آسا اسکریپت:آموزش شاخه های گیت

 حالا با استفاده از دستور git checkout developer به شاخه developer وارد شوید و همون تغییرات فوق را در تگ پاراگراف انجام دهید و به جای کلمه development از کلمه master استفاده کنید.

Aboutus.html
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <header>
        <h1>aboutus</h1>
    </header>
    <p>changes on development branch</p>
</body>
</html>

و در نهایت این مقادیر را نیز commit کنید. 

به شاخه master باز گردید. و با استفاده از دستور زیر شاخه development را بر روی شاخه master ترکیب کنید.

$ git merge development

با وارد کردن دستور فوق خروجی زیر را دریافت می کنیم.

$ git merge development
Auto-merging aboutus.html
CONFLICT (content): Merge conflict in aboutus.html
Automatic merge failed; fix conflicts and then commit the result.

همانطور که مشاهده می کنید تداخل یا همان conflict بر روی شاخه ها در هنگام merging به وجود آمده است و حالت خط فرمان git به صورت (master|MERGING) شده است.

در این جا چندین دو راه حل برای رفع کردن این مشکل وجود دارد.

می تونید کلا عملیات ترکیب سازی را لغو کنید و دوباره تغییرات را انجام دهید. برای این کار از دستور زیر استفاده کنید.

$ git merge --abort

و سپس تداخل را اصلاح کرده ودوباره فرآیند ترکیب را انجام دهید.

 

نکته: برای اصلاح کردن conflict بهترین راه حل استفاده از اصلاح گر های کد است. می توانید از اصلاح گر visual studio code استفاده کنید ویا اگر برنامه نویس php هستید از php storm استفاده کنید.

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

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <header>
        <h1>aboutus</h1>
    </header>
<<<<<<< HEAD
    <p>changes on master branch</p>
=======
    <p>changes on development branch</p>
>>>>>>> development
</body>
</html>

در پائین تگ header برای پاراگراف های master و branch تداخل ایجاد شده است. در این جا اولویت master برای ما بیشتر است پس در نتیجه قسمت شاخه development را پاک می کنیم. در خروجی داریم:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <header>
        <h1>aboutus</h1>
    </header>
    <p>changes on master branch</p>
</body>
</html>

بعد از انجام این تغییرات اگر git status بگیریم خروجی گیت به صورت زیر است:

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   aboutus.html

no changes added to commit (use "git add" and/or "git commit -a")

اگر به خروجی توجه کنید در کنار تغییرات نوشته شده است both modified که در حالت عادی به صورت modified نوشته می شود. حالا با استفاده از دستور زیر ابتدا تغییرات را به حالت stage می بریم و سپس توسط دستور commit آن را commit  می کنیم.

$ git add .
$ git commit -m "conflict resolved"

حالا اگر git status بگیریم مشاهده می کنیم که مشکل merging کاملا برطرف شده است و development بر روی master به سادگی ترکیب شده است.

برای تمرین بیشتر شرایط تداخل بر روی style.css را نیز به صورت conflict برطرف می کنیم. 

ابتدا بر روی شاخه master وارد فایل style.css می شویم و قطعه کد زیر را وارد می کنیم. تغییرات را در شاخه commit می کنیم.

body {
    color: #ffff;
}

سپس وارد شاخه development شده و تغییراتی را به صورت زیر در درون style.css ذخیره می کنیم.

html {
    background-color: #0000;
}

حالا با استفاده از دستور git checkout master وارد شاخه master می شویم و دستور زیر را جهت merge کردن شاخه development با master انجام می دهیم.

$ git merge development
Auto-merging style/style.css
CONFLICT (content): Merge conflict in style/style.css
Automatic merge failed; fix conflicts and then commit the result.

بعد از وارد کردن این گزینه وارد style.css می شویم و مشاهده می کنیم که دوباره conflict ایجاد شده است. تداخل ها را به صورت زیر اصلاح می کنیم و سپس فایل را ذخیره می کنیم.

body {
    color: #ffff;
}
html {
    background-color: #0000;
}

حالا می توانیم با استفاده از دستورات زیر که در قسمت قبل نیز از آن ها استفاده کردیم پروژه را به سادگی merge کرده  و تداخلات را برطرف کنیم.

$ git add .
$ git commit -m "conflict resolved"

جمع بندی

تمرکز ما در این جلسه به طور کامل بر روی conflict و یا به فارسی همان تداخل ها بود. این تداخل ها را در دو مورد ایجاد کردیم و به سادگی با اصلاح کدها برطرف نمودیم. مورد اول تداخل به وجود آمده بر روی فایل about.html بود که مرتفع شد و مورد دوم تداخل به وجود آمده بر روی style.css بود که با روشی مشابه مثال قبل این تداخل نیز برطرف گردید و merging به خوبی انجام پذیرفت.
 

لیست قسمت های این دوره:
رایگان 20 دقیقه
رایگان 30 دقیقه
رایگان 35 دقیقه
رایگان 15 دقیقه
رایگان 5 دقیقه