Git 2026

فصل ۷ · ادغام و تعارض

ادغام — fast-forward، merge commit و تعارض

Merge یعنی دو خط تاریخچه را یکی کنی. اگر هر دو خط همان خطوط فایل را جور دیگری عوض کرده باشند، Git نمی‌داند کدام درست است — به آن تعارض می‌گویند و باید خودت انتخاب کنی.

🎯 اهداف یادگیری

  • fast-forward را از merge commit تشخیص دهی
  • تعارض را در VS Code با دکمه‌های Accept حل کنی
  • --no-ff و --squash را بدانی کی استفاده کنی
  • abort کنی وقتی اوضاع خراب شد

🧬 سه شکل ادغام

سناریوی آموزشی
git switch main
git merge feat/auth
نوع کی رخ می‌دهد نتیجه
Fast-forward از وقتی شاخه را ساختی، main هیچ کامیت جدیدی نگرفته Git فقط برچسب main را روی همان کامیت‌های شاخه جلو می‌کشد؛ کامیت ادغام ساخته نمی‌شود
Merge commit هر دو طرف بعد از جدایی کامیت جدید دارند یک کامیت جدید با دو والد ساخته می‌شود
Squash merge معمولاً دکمهٔ GitHub همهٔ کامیت‌های شاخه در یک کامیت روی هدف خلاصه می‌شوند؛ جزئیات میانی در main نمی‌ماند
مقایسه merge و rebase

شکل ۵ — merge تاریخچه را حفظ می‌کند؛ rebase آن را خطی می‌کند (جزئیات در فصل ۲۳).

GitHub و --no-ff

بسیاری از تیم‌ها Create a merge commit را می‌خواهند تا هر PR یک گره قابل‌ردیابی داشته باشد. معادل محلی: git merge --no-ff feat/auth.

💥 تعارض — آناتومی

تعارض وقتی است که Git نمی‌تواند دو تغییر روی یک hunk را ترکیب کند.

نشانه‌های تعارض در فایل
<<<<<<< HEAD
return token;
=======
return rotate(token);
>>>>>>> feat/auth

سه نسخه در ذهن داشته باش:

  • Ours / Current = شاخه‌ای که روی آن هستی (HEAD)
  • Theirs / Incoming = شاخه‌ای که merge می‌کنی
  • Base = جد مشترک (برای merge سه‌طرفه)
حل تعارض در VS Code

شکل ۶ — CodeLens: Accept Current، Accept Incoming، Accept Both، Compare Changes.

مسیر حل در VS Code

  1. Source Control بخش Merge Changes را نشان می‌دهد
  2. فایل را باز کن — نوار CodeLens بالای تعارض
  3. انتخاب کن یا دستی ویرایش کن
  4. فایل را Stage کن (علامت تعارض تمام می‌شود)
  5. Commit ادغام را کامل می‌کند
ترمینال هم‌ارز
git merge --abort              # پشیمانی قبل از commit
git merge --continue           # بعد از حل
git diff --name-only --diff-filter=U
Accept Both کورکورانه

هر دو را پذیرفتن گاهی کد syntactically درست و semantically غلط می‌سازد. همیشه تست را اجرا کن.

🧰 استراتژی‌های پیشرفتهٔ merge

ابزارها
git merge -X ours feat/x       # در تعارض، ما برنده
git merge -X theirs feat/x
git log --merge                # فقط کامیت‌های درگیر تعارض
git checkout --conflict=diff3 -- file

diff3 جد مشترک را هم نشان می‌دهد — برای تعارض سخت طلایی است. در VS Code: "merge-conflict.diff3": true (یا Merge Editor).

VS Code Merge Editor سه‌ستونه (Incoming / Current / Result) را از Command Palette با Merge Conflict: Open Merge Editor باز می‌کند.

سؤالات مصاحبه (با پاسخ)

Junior — fast-forward یعنی چه؟ حرکت اشاره‌گر بدون کامیت جدید، چون تاریخچه خطی بوده.

Mid — چرا squash در main تاریخچه را «دروغ» می‌کند؟ چون چند کامیت واقعی به یک کامیت تبدیل می‌شوند؛ bisect و blame جزئیات را از دست می‌دهند — ولی PR تمیز می‌ماند.

Senior — recursive در برابر ort؟ از Git ۲.۳۴ موتور پیش‌فرض ort است؛ سریع‌تر و پیش‌بینی‌پذیرتر از recursive قدیمی.

✅ چک‌لیست فهم

  • سه نوع ادغام را بلدی
  • تعارض را در VS Code حل کرده‌ای
  • merge --abort را حفظی بلدی
  • می‌دانی squash چه چیزی را پنهان می‌کند

فصل بعد: Undo — نجات بدون وحشت.

فصل ۷ از ۳۶ · مرجع جامع و حرفه‌ای Git و GitHub · ویرایش 1.0.0