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 آن را خطی میکند (جزئیات در فصل ۲۳).
بسیاری از تیمها 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 سهطرفه)
شکل ۶ — CodeLens: Accept Current، Accept Incoming، Accept Both، Compare Changes.
مسیر حل در VS Code
- Source Control بخش Merge Changes را نشان میدهد
- فایل را باز کن — نوار CodeLens بالای تعارض
- انتخاب کن یا دستی ویرایش کن
- فایل را Stage کن (علامت تعارض تمام میشود)
- Commit ادغام را کامل میکند
git merge --abort # پشیمانی قبل از commit git merge --continue # بعد از حل git diff --name-only --diff-filter=U
هر دو را پذیرفتن گاهی کد 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 — نجات بدون وحشت.