Merge — عملیاتی در Git است که تغییرات را از یک شاخه به شاخه دیگر ادغام میکند و یک commit ادغام (merge commit) ایجاد میکند. Git از چندین استراتژی پشتیبانی میکند: fast-forward (تاریخ خطی)، three-way merge (با ایجاد merge commit) و squash merge (فشردهسازی همه commitها در یک commit). طبق دادههای git-scm.com, 2025، merge همچنان پرکاربردترین مکانیزم یکپارچهسازی کد در توسعه تیمی با Git است.
نکات اصلی
Merge (ادغام) — یک عملیات اساسی در Git است که تغییرات را از یک شاخه (source) به شاخه دیگر (target) ادغام میکند. در نتیجه ادغام، شاخه هدف تمام commitهایی را که در شاخه مبدأ وجود داشته و در آن نبوده است دریافت میکند. بسته به شرایط، Git میتواند merge را به سه روش مختلف انجام دهد.
ارزش اصلی merge — حفظ تاریخ است: merge commit واقعیت ادغام شاخهها را ثبت میکند، اطلاعات مربوط به زمان و اینکه کدام شاخهها ادغام شدهاند را حفظ میکند. این کار حسابرسی تغییرات، جستجوی رگرسیونها و درک گاهشماری توسعه را تسهیل میکند. در پروژههای بزرگ، merge commit روش استاندارد یکپارچهسازی کد است.
طبق دادههای GitLab Flow، merge commitها در ۷۳٪ تیمهایی که با Git کار میکنند استفاده میشود. رویکردهای جایگزین (rebase, squash) توسط تیمهایی که به تاریخ خطی تمایل دارند ترجیح داده میشود. انتخاب استراتژی به اندازه تیم، فراوانی انتشار و توافقات پذیرفتهشده در پروژه بستگی دارد.
Merge زمانی لازم است که توسعهدهنده کار روی یک ویژگی را تمام کرده و میخواهد آن را در develop یا main ادغام کند. سناریوی معمول: توسعهدهنده یک شاخه ویژگی از develop ایجاد کرد، چند روز روی آن کار کرد و در این مدت commitهای جدیدی از سایر شرکتکنندگان در develop ظاهر شد. قبل از ادغام باید تغییرات را ترکیب کرد — و برای این کار از merge استفاده میشود.
بدون merge امکان کار گروهی روی یک کد در Git وجود ندارد. هر بار که دو توسعهدهنده به طور همزمان تغییراتی را در یک پایگاه کد وارد میکنند، شاخههای آنها از هم جدا میشود. Merge — تنها راه برای بازگرداندن این تغییرات بدون از دست دادن دادهها است.
Git از سه نوع merge پشتیبانی میکند که هر کدام برای سناریوی خاص خود طراحی شدهاند. انتخاب نوع ادغام بر تاریخ commitها، راحتی بازگشت و خوانایی لاگ تأثیر میگذارد.
Fast-forward زمانی رخ میدهد که شاخه هدف از زمان ایجاد شاخه مبدأ commit جدیدی نداشته باشد. در این حالت Git به سادگی نشانگر شاخه هدف را به جلو، به آخرین commit شاخه مبدأ منتقل میکند. تاریخ بدون merge commit خطی باقی میماند.
# Fast-forward merge: develop از زمان ایجاد feature تغییر نکرده است
git checkout develop
git merge feature/new-login
# نتیجه: نشانگر develop به انتهای feature منتقل شد
# هیچ merge commitای ایجاد نشد
Fast-forward برای شاخههای کوتاهعمر مناسب است، جایی که توسعهدهنده به تنهایی کار میکرد. اما این رویکرد یک اشکال دارد: اطلاعات مربوط به وجود شاخه از دست میرود — همه commitها به نظر میرسند که مستقیماً در develop انجام شدهاند.
Three-way merge زمانی اجرا میشود که هر دو شاخه بعد از نقطه واگرایی commitهای جدیدی داشته باشند. Git یک commit ادغام جداگانه با دو والد ایجاد میکند که واقعیت ادغام شاخهها را ثبت میکند. این رویکرد برای شاخههای ویژگی در توسعه تیمی توصیه میشود.
# Three-way merge اجباری با پرچم --no-ff
git checkout develop
git merge --no-ff feature/new-login
# merge commit با پیام پیشفرض ایجاد شد
# میتوانید پیام خود را از طریق -m تنظیم کنید
git merge --no-ff feature/new-login -m "Merge feature/new-login into develop"
پرچم --no-ff ایجاد merge commit را تضمین میکند، حتی اگر fast-forward ممکن باشد. این بهترین روش برای حفظ اطلاعات مربوط به انشعاب در پروژه است.
Squash merge همه commitهای شاخه مبدأ را در یک commit فشرده کرده و به شاخه هدف اعمال میکند. تاریخچه ویژگی از بین میرود — یک commit با تمام تغییرات وارد شاخه میشود. این زمانی مفید است که commitهای جزئی در شاخه ویژگی برای تاریخ کلی ارزشی ندارند.
# Squash merge: همه commitهای feature در یک commit فشرده شدند
git checkout develop
git merge --squash feature/experimental
git commit -m "feat: experimental login flow (squashed)"
Squash برای پیشنویسها، شاخههای آزمایشی و موقعیتهایی که حفظ تمیزی تاریخ مهم است مناسب است. نکته منفی — ارتباط با commitهای اصلی از دست میرود که بازگرداندن تغییرات جداگانه را دشوار میکند.
Ours و Theirs — دو استراتژی ویژه merge در Git. Ours تغییرات شاخه مبدأ را کاملاً نادیده میگیرد و فقط آنچه را که در شاخه هدف است حفظ میکند. Theirs برعکس، در هر تعارضی نسخه شاخه مبدأ را میپذیرد. این استراتژیها هنگام ادغام حجم زیادی از کد مفید هستند، زمانی که از قبل مشخص است کدام نسخه باید پیروز شود.
مکانیزم merge در Git بر اساس مقایسه سه نقطه است: جد مشترک (merge base)، وضعیت شاخه مبدأ و وضعیت شاخه هدف. Git merge base — آخرین commit مشترک برای هر دو شاخه — را پیدا میکند و محاسبه میکند که چه تغییراتی در هر شاخه پس از واگرایی رخ داده است.
Git از الگوریتم سهجانبه ادغام استفاده میکند که نه تنها دو نسخه مقایسهشده فایل، بلکه جد مشترک آنها را نیز در نظر میگیرد. به لطف این، Git میتواند به طور خودکار موقعیتهایی را حل کند که تغییرات در یک شاخه به بخشهای تغییر یافته شاخه دیگر برخورد نمیکند — حتی اگر هر دو فایل تغییر کرده باشند.
سناریو را در نظر بگیرید: دو توسعهدهنده روی فایلهای مختلف در یک شاخه ویژگی کار میکنند. اولی LoginActivity.kt را تغییر داد، دومی ProfileFragment.kt را. وقتی تغییرات خود را ادغام میکنند، Git میبیند که تغییرات به فایلهای مختلف مربوط میشوند و merge را به طور خودکار بدون دخالت انسان انجام میدهد.
اگر هر دو توسعهدهنده LoginActivity.kt را تغییر دادهاند، اما در متدهای مختلف — Git نیز به طور خودکار از عهده برمیآید و تغییرات را خط به خط ترکیب میکند. تعارض فقط زمانی ایجاد میشود که هر دو خطوط یکسان را تغییر داده باشند یا یکی کدی را حذف کرده باشد که دیگری تغییر داده است.
تعارض merge زمانی ایجاد میشود که Git نمیتواند تغییرات را به طور خودکار ترکیب کند، زیرا هر دو شاخه خطوط یکسان را به طور متفاوت تغییر دادهاند. در این حالت Git بخشهای دارای تعارض را در فایلها علامتگذاری میکند و منتظر حل دستی توسط توسعهدهنده میماند.
بخشهای دارای تعارض با نشانگرهای خاصی علامتگذاری میشوند: <<<<<<< HEAD کد شاخه هدف را نشان میدهد، ======= — جداکننده، >>>>>>> source-branch — کد شاخه مبدأ. توسعهدهنده باید به صورت دستی انتخاب کند کدام گزینه را نگه دارد یا آنها را ترکیب کند.
# ۱. اجرای merge و مشاهده تعارض
git merge feature/new-login
# خروجی: CONFLICT (content): Merge conflict in LoginActivity.kt
# ۲. مشاهده لیست فایلهای دارای تعارض
git status
# both modified: src/ui/login/LoginActivity.kt
# ۳. حل تعارض: ویرایش فایل، حذف نشانگرها
# ۴. اضافه کردن فایل حلشده و اتمام merge
git add src/ui/login/LoginActivity.kt
git merge --continue
# یا: git commit (بدون --continue)
برای حل تعارضات ابزارهایی وجود دارند: git mergetool یک ادغامکننده بصری باز میکند (Meld, Beyond Compare, VS Code). بسیاری از توسعهدهندگان ترجیح میدهند تعارضات را در IDE حل کنند — IntelliJ IDEA و Android Studio ابزار داخلی با مقایسه سهپنلای ارائه میدهند که این فرآیند را به طور قابل توجهی ساده میکند.
نکاتی برای حل تعارضات: همیشه بفهمید هر طرف تعارض چه کاری انجام میدهد، کد دیگران را بدون درک منطق آن حذف نکنید و اگر تعارض خیلی پیچیده است — نویسنده هر دو شاخه را برای حل مشترک مشارکت دهید.
انتخاب بین Merge و Rebase — یکی از رایجترین تصمیمات معماری در Git است. هر دو رویکرد تغییرات را ترکیب میکنند، اما به روشهای مختلف: merge تاریخ انشعاب را حفظ میکند، rebase تاریخ را بازنویسی میکند و آن را خطی میکند.
بسیاری از تیمها از رویکرد ترکیبی استفاده میکنند: rebase برای بهروزرسانی شاخه ویژگی به وضعیت فعلی develop (git rebase develop)، سپس merge با پرچم --no-ff برای ثبت ادغام. این کار تاریخ تمیزی درون ویژگی و نقاط ادغام اطلاعاتی در سطح develop فراهم میکند.
سوالات متداول
بدون --no-ff Git در صورت امکان fast-forward merge را انجام میدهد — به سادگی نشانگر شاخه را جابجا میکند. با --no-ff Git همیشه یک merge commit ایجاد میکند و اطلاعات مربوط به انشعاب را حفظ میکند. برای شاخههای ویژگی در توسعه تیمی توصیه میشود.
از git mergetool یا ابزار داخلی IDE استفاده کنید. اگر تعارض دهها فایل را تحت تأثیر قرار میدهد — احتمالاً شاخهها بیش از حد از هم فاصله گرفتهاند. در این صورت بهتر است با تیم در مورد برنامه ادغام بحث کنید، احتمالاً آن را به چند مرحله تقسیم کنید.
بله: git merge --abort merge را لغو میکند، اگر هنوز کامل نشده باشد (تعارض). اگر merge قبلاً کامل شده است — برای بازگشت ایمن از git reset --hard HEAD~1 یا git revert -m 1 <merge-commit> استفاده کنید.
برای کار تیمی توصیه میشود. Merge commit واقعیت ادغام را ثبت میکند، شامل ارجاع به هر دو شاخه است و درک تاریخ را ساده میکند. برای شاخههای شخصی یا آزمایشی، squash merge یا fast-forward قابل قبول است.
Git نمیتواند فایلهای باینری را به طور خودکار ادغام کند — یکی از نسخهها را به طور کامل انتخاب میکند. برای فایلهای باینری (تصاویر، .aab، .apk) توصیه میشود تغییرات همزمان را به حداقل برسانید و برای فایلهای بزرگ از Git LFS استفاده کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید