ادغام (merge) — چیست، چگونه merge کار می‌کند و استراتژی‌های ادغام

نویسنده: IT Sectr منتشر شده: 2026-08-01 زمان مطالعه: 9 دقیقه

Merge — عملیات ادغام شاخه‌ها در Git است که تغییرات دو خط توسعه مختلف را در یک شاخه هدف ترکیب می‌کند. برخلاف rebase، merge تاریخچه کامل انشعاب را حفظ می‌کند و یک commit ادغام ویژه با دو والد ایجاد می‌کند. طبق مستندات رسمی Git (2026)، merge امن‌ترین روش ادغام شاخه‌ها است، زیرا تاریخچه را بازنویسی نمی‌کند و امکان ردیابی زمان و شاخه‌های ادغام شده را فراهم می‌کند. این انتخاب استاندارد برای ادغام در شاخه‌های عمومی مانند main، develop و release است.

نکات اصلی

  • Merge — ادغام شاخه‌ها با ایجاد commit ادغام که تاریخچه هر دو شاخه را حفظ می‌کند.
  • Commit ادغام — commit ویژه با دو والد که واقعیت ادغام را ثبت می‌کند.
  • استراتژی‌های ادغام — recursive, octopus, ours, squash — هر کدام برای سناریوهای مختلف مناسب هستند.
  • تعارضات — هنگام تغییر همزمان خطوط یکسان در هر دو شاخه ایجاد می‌شوند و نیاز به حل دستی دارند.
  • امنیت — merge commitهای موجود را تغییر نمی‌دهد، بنابراین برای شاخه‌های عمومی بی‌خطر است.

merge در Git چیست

Merge — دستور git merge است که تغییرات شاخه مشخص شده را در شاخه فعلی ادغام می‌کند. Git جد مشترک (commit پایه مشترک) را پیدا می‌کند، diff هر شاخه نسبت به جد را محاسبه می‌کند و commit ادغامی ایجاد می‌کند که مجموعه ترکیبی تغییرات را شامل می‌شود. نتیجه — شاخه هدف با تمام تغییرات شاخه ادغام شده تکمیل می‌شود.

نحو: در شاخه هدف (مثلاً main) قرار گرفته و git merge feature را اجرا کنید. اگر تعارضی نباشد، Git به طور خودکار commit ادغام ایجاد می‌کند. در پیام پیش‌فرض commit ادغام نوشته می‌شود: «Merge branch 'feature' into main». پیام را می‌توان با پرچم -m تغییر داد یا در ویرایشگر باز شده ویرایش کرد.

Merge یک عملیات غیرمخرب است. برخلاف rebase، merge commitهای موجود را تغییر نمی‌دهد: آنها با همان هش‌ها، نویسندگان و تاریخ‌ها باقی می‌مانند. این باعث می‌شود merge تنها روش امن ادغام برای شاخه‌هایی باشد که چند برنامه‌نویس همزمان روی آنها کار می‌کنند. اگر چیزی اشتباه پیش برود، merge را می‌توان با دستور git merge --abort لغو کرد.

bash
# به شاخه هدف سوئیچ کن
git checkout main

# شاخه ویژگی را ادغام کن
git merge feature

# نتیجه — commit ادغام با دو والد
git log --oneline --graph

# ادغام با پیام سفارشی
git merge feature -m "feat: integrate authentication module"

انواع merge: regular, squash, fast-forward

Git از سه حالت ادغام پشتیبانی می‌کند که بسته به نتیجه مورد نظر انتخاب می‌شوند. Regular merge (پیش‌فرض) commit ادغام ایجاد می‌کند. Squash merge تمام commitهای شاخه ویژگی را در یکی ادغام می‌کند. Fast-forward — نشانگر شاخه را بدون ایجاد commit به جلو می‌برد، در صورت امکان. انتخاب حالت به workflow تیم و قوانین تاریخچه بستگی دارد.

Regular merge (--no-ff) — حتی اگر ادغام به صورت fast-forward امکان‌پذیر باشد commit ادغام ایجاد می‌کند. برای شاخه main توصیه می‌شود: commit ادغام لحظه ادغام ویژگی را مشخص می‌کند و امکان بازگرداندن آسان تمام تغییرات شاخه ویژگی را با یک revert از commit ادغام فراهم می‌کند. GitHub به طور پیش‌فرض از این حالت هنگام ادغام PR از طریق دکمه Merge استفاده می‌کند.

Squash merge (--squash) — تمام commitهای شاخه ویژگی را در یک commit در شاخه هدف جمع می‌کند. زمانی مفید است که تاریخچه اولیه شاخه ویژگی نباید وارد main شود. عیب: ارتباط با commitهای اصلی از بین می‌رود — نمی‌توان دید که ویژگی گام به گام چگونه توسعه یافته است. GitHub هنگام انتخاب «Squash and merge» در PR از این حالت استفاده می‌کند.

Fast-forward (--ff) — اگر شاخه هدف پس از انشعاب ویژگی commit جدیدی نداشته باشد، Git به سادگی نشانگر را بدون ایجاد commit ادغام به جلو می‌برد. تاریخچه خطی می‌ماند. پرچم --no-ff به اجبار commit ادغام ایجاد می‌کند، --ff-only در صورت عدم امکان fast-forward با خطا پایان می‌یابد.

bash
# commit ادغام اجباری (توصیه شده برای main)
git merge --no-ff feature

# Squash merge — تمام commitها در یکی
git merge --squash feature
git commit -m "feat: add authentication"

# Fast-forward فقط در صورت امکان
git merge --ff-only feature

# لغو ادغام دارای تعارض
git merge --abort

استراتژی‌های ادغام Git

استراتژی‌های ادغام الگوریتمی را تعیین می‌کنند که Git برای ترکیب تغییرات استفاده می‌کند. هر استراتژی برای سناریوهای مختلف مناسب است. Git به طور خودکار استراتژی مناسب را انتخاب می‌کند، اما برنامه‌نویس می‌تواند آن را به صراحت با پرچم --strategy مشخص کند. درک استراتژی‌ها به پیش‌بینی رفتار Git در ادغام‌های پیچیده کمک می‌کند.

Recursive — استراتژی پیش‌فرض برای ادغام دو شاخه. Git جد مشترک را پیدا می‌کند، تغییرات هر شاخه را محاسبه کرده و آنها را ادغام می‌کند. اگر جد مشترک پیدا شود، recursive تغییر نام فایل‌ها و افزودن فایل‌های جدید را به درستی مدیریت می‌کند. در تعارضات، recursive می‌تواند از گزینه‌های اضافی استفاده کند: ours (انتخاب خودکار نسخه ما) و theirs (انتخاب نسخه آنها).

Octopus — برای ادغام همزمان بیش از دو شاخه: git merge feature1 feature2 feature3. Octopus از حل تعارض پشتیبانی نمی‌کند — تمام تعارضات باید قبل از اجرای دستور حل شوند. به ندرت استفاده می‌شود، عمدتاً برای ادغام چند شاخه مستقل که تضمین شده با هم تداخل ندارند (مثلاً ماژول‌های مختلف).

استراتژیتعداد شاخه‌هاحل تعارض
Recursive2خودکار + گزینه‌های ours/theirs
Octopus3+خیر — تمام تعارضات باید از قبل حل شوند
Oursهر تعدادهمیشه نسخه ما را انتخاب می‌کند، تغییرات دیگران نادیده گرفته می‌شوند
Subtree2برای ادغام زیردرخت (subtree merge)

Ours — استراتژی ویژه‌ای که تغییرات شاخه ادغام شده را کاملاً نادیده می‌گیرد و محتوای فعلی شاخه هدف را حفظ می‌کند. commit ادغام ایجاد می‌شود، اما محتوا بدون تغییر می‌ماند. زمانی مفید است که نیاز به ثبت واقعیت ادغام در تاریخچه دارید، اما عملاً تمام تغییرات شاخه دیگر را رد می‌کنید.

حل تعارضات merge

تعارض merge زمانی رخ می‌دهد که خطوط یکسان یک فایل در هر دو شاخه به طور متفاوت تغییر کرده باشند. Git نمی‌تواند به طور خودکار تعیین کند کدام نسخه صحیح است و ادغام را متوقف می‌کند. تعارض همچنین می‌تواند هنگام تغییر نام فایل در یک شاخه و تغییر آن در شاخه دیگر، یا هنگام حذف و تغییر همزمان یک فایل رخ دهد.

فرآیند حل: Git فایل‌های دارای تعارض را با نشانگرها علامت‌گذاری می‌کند. در فایل بخش‌هایی با <<<<<<< HEAD (نسخه ما)، ======= (جداکننده) و >>>>>>> feature (نسخه آنها) ظاهر می‌شوند. برنامه‌نویس به صورت دستی بخش تعارض را ویرایش می‌کند، خطوط مورد نیاز از هر دو نسخه را انتخاب می‌کند، نشانگرها را حذف می‌کند، فایل را ذخیره کرده و با git add به ایندکس اضافه می‌کند.

برای حل بصری تعارضات، Git از mergetool — ابزار مقایسه خارجی پشتیبانی می‌کند. ابزارهای mergetool محبوب: Meld، KDiff3، Beyond Compare، VS Code (ویرایشگر داخلی تعارض). Mergetool سه پنل نمایش می‌دهد: نسخه ما، نسخه آنها و نتیجه. برنامه‌نویس بصری بلوک‌های کد را برای درج در فایل نهایی انتخاب می‌کند.

bash
# شروع ادغام و تشخیص تعارض
git merge feature
# تعارض (محتوا): تعارض ادغام در src/main.swift

# بررسی فایل‌های دارای تعارض
git status

# باز کردن mergetool بصری
git mergetool

# پس از حل — افزودن و commit
git add src/main.swift
git commit

# لغو ادغام
git merge --abort

چه زمانی merge را به جای rebase انتخاب کنیم

merge بر rebase ارجحیت دارد در چند موقعیت کلیدی. اول: هنگام کار با شاخه‌های عمومی که در دسترس سایر برنامه‌نویسان هستند. Merge تاریخچه را بازنویسی نمی‌کند و همکاران می‌توانند با امنیت همگام‌سازی کنند. Rebase در یک شاخه عمومی تاریخچه واگرا و تعارضاتی برای همه کسانی که commitهای قدیمی را دریافت کرده‌اند ایجاد می‌کند.

دومین موقعیت: هنگام تکمیل شاخه ویژگی. بیشتر تیم‌ها merge (با پرچم --no-ff) به main را ترجیح می‌دهند تا لحظه ادغام ویژگی را ثبت کنند. این کار پیمایش تاریخچه را ساده می‌کند و امکان بازگرداندن آسان کل ویژگی را با یک git revert از commit ادغام فراهم می‌کند. GitHub Flow به طور پیش‌فرض سه گزینه merge ارائه می‌دهد: merge ساده، squash merge و rebase merge.

سومین موقعیت: هنگام کار با pull request که بررسی شده است. GitHub و GitLab دکمه merge را با گزینه‌های مختلف ارائه می‌دهند. Merge (Create a merge commit) — تاریخچه کامل با commit ادغام. Squash and merge — تاریخچه تمیز بدون جزئیات توسعه. Rebase and merge — تاریخچه خطی بدون commit ادغام، اما با بازنویسی commitها. انتخاب به قوانین تیم بستگی دارد.

  • شاخه‌های عمومی (main, develop) — فقط merge، هرگز rebase.
  • تکمیل PR — merge با --no-ff برای ثبت لحظه ادغام.
  • شاخه‌های با commitهای دیگران — merge کار دیگران را بازنویسی نمی‌کند.
  • قبل از انتشار — merge امن‌تر است، زیرا ریسک کمتری دارد.
  • شاخه مشترک — اگر چند برنامه‌نویس روی شاخه کار می‌کنند، merge اجباری است.

بهترین روش‌های ادغام شاخه‌ها

قاعده اول: همیشه قبل از merge در نسخه به‌روز شاخه هدف باشید. قبل از ادغام ویژگی، git checkout main && git pull را اجرا کنید. این کار تعارضات را به حداقل می‌رساند و تضمین می‌کند که commit ادغام تمام تغییرات به‌روز را شامل می‌شود. اگر شاخه هدف بسیار جلو رفته است، ابتدا git merge main را در داخل شاخه ویژگی اجرا کنید تا تعارضات در بافت آن حل شوند.

قاعده دوم: کد را پس از merge آزمایش کنید. Merge ممکن است رفتار را تغییر دهد، حتی اگر تعارضی نبوده باشد. خط لوله CI/CD باید آزمایش‌ها را روی commit ادغام قبل از ارسال به تولید اجرا کند. برخی تیم‌ها از merge gates — بررسی‌های اجباری که merge را تا عبور از آنها مسدود می‌کنند — استفاده می‌کنند.

قاعده سوم: commitهای ادغام را مستند کنید. پیام استاندارد «Merge branch 'feature' into main» چندان مفید نیست. توصیه می‌شود توضیح آنچه ادغام شده اضافه شود: «Merge authentication module: login, registration, password recovery». این کار تحلیل تاریخچه و جستجوی پسرفت‌ها را ساده می‌کند. در پروژه‌های بزرگ، commitهای ادغام به طور خودکار از نام PR تولید می‌شوند.

  • به‌روزرسانی — قبل از merge مطمئن شوید شاخه هدف به‌روز است (git pull).
  • آزمایش — CI/CD باید آزمایش‌ها را روی commit ادغام نتیجه اجرا کند.
  • پیام‌های توصیفی — در commit ادغام مشخص کنید کدام ویژگی ادغام شده است.
  • تناوب — شاخه‌های ویژگی را هر چه زودتر و بیشتر ادغام کنید (حداکثر یک هفته).
  • لغو — git revert از commit ادغام کل ویژگی را به طور کامل بازمی‌گرداند.

سؤالات متداول

ادغام (merge) شاخه‌ها در Git به چه معناست؟

ادغام (merge) — اجرای git merge برای ترکیب تغییرات از یک شاخه به شاخه دیگر. نتیجه یک commit ادغام است که واقعیت ادغام را ثبت می‌کند و شامل تغییرات هر دو شاخه است. این روش اصلی ادغام شاخه‌های ویژگی در main، develop یا release در Git Flow است.

تفاوت squash merge با merge معمولی چیست؟

Squash merge تمام commitهای شاخه ویژگی را در یک commit در شاخه هدف ادغام می‌کند و تاریخچه توسعه میانی را از دست می‌دهد. merge معمولی یک commit ادغام ایجاد می‌کند و تمام commitهای شاخه ویژگی را حفظ می‌کند. Squash merge تاریخچه تمیزی ارائه می‌دهد، اما امکان ردیابی توسعه گام به گام ویژگی را نمی‌دهد.

چگونه تعارض merge را در Git حل کنیم؟

فایل دارای تعارض را باز کنید، بخش‌های دارای نشانگر <<<<<<< HEAD و >>>>>>> را پیدا کنید. محتوا را ویرایش کنید، خطوط مورد نیاز از هر دو نسخه را نگه دارید، نشانگرها را حذف کنید. فایل را ذخیره کنید، git add و git commit را اجرا کنید. می‌توانید از git mergetool برای حل بصری استفاده کنید.

چه زمانی از merge به جای rebase استفاده کنیم؟

Merge همیشه برای شاخه‌های عمومی (main, develop, release) استفاده می‌شود، زیرا تاریخچه را بازنویسی نمی‌کند. Rebase در شاخه‌های ویژگی شخصی قبل از انتشار آنها اعمال می‌شود. پس از اینکه شاخه به بخشی از مخزن مشترک تبدیل شد و همکاران به آن مراجعه کردند، فقط merge مجاز است.

چگونه merge را در Git لغو کنیم؟

قبل از تکمیل merge (در حین تعارض) — git merge --abort ادغام را به طور کامل لغو می‌کند. پس از تکمیل — git revert <merge-commit-hash> -m 1 یک commit بازگشتی ایجاد می‌کند. پرچم -m 1 مشخص می‌کند کدام شاخه والد حفظ شود (هدف). Git revert برای شاخه‌های منتشر شده از git reset ایمن‌تر است.

خلاصه

  • Merge — ادغام ایمن شاخه‌ها با حفظ تاریخچه و ایجاد commit ادغام با دو والد.
  • حالت‌های ادغام — regular (--no-ff)، squash (--squash) و fast-forward (--ff) برای اهداف مختلف.
  • استراتژی‌ها — recursive (پیش‌فرض)، octopus (3+ شاخه)، ours (نادیده گرفتن تغییرات دیگران).
  • تعارضات — به صورت دستی با ویرایش بخش‌های نشانه‌گذاری شده یا mergetool حل می‌شوند.
  • امنیت — merge commitهای موجود را تغییر نمی‌دهد، بنابراین برای شاخه‌های عمومی بی‌خطر است.
  • Squash merge — تمام commitها را در یکی ادغام می‌کند و تاریخچه توسعه میانی را از دست می‌دهد.
  • لغو merge — git revert از commit ادغام با پرچم -m 1 برای بازگرداندن ایمن تغییرات منتشر شده.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید