Future ForgeFuture ForgeFuture ForgeFuture Forge
ServicesWorkPackagesFree toolsNotesAboutContact
Start
  1. Home
  2. /Notes
Future ForgeFuture Forge

Product engineering studio — design, build, and deploy software.

Discuss your project

Contact

hello@futureforge.ir09128464105
Future ForgeFuture Forge

Product engineering studio — design, build, and deploy software.

Services

Product engineeringFull-stack engineeringEngineering auditArchitecture consultingInfrastructure and deploymentAI in the product

Explore

WorkNotesFAQPackages

Free tools

Engineering auditArchitecture advisorProject estimatorPrompt tool

Company

AboutContactPrivacyTerms of use

Discuss your project

Describe the problem and the constraints. If there is a fit, we will schedule a conversation.

Discuss your project

Contact

hello@futureforge.ir09128464105
GitHubLinkedIn

© 2026 FutureForge. All rights reserved.

HomeServicesFree toolsStart
Glossary

Merge در Git چگونه کار می‌کند؟ Fast-forward، سه طرفه و Commit ادغام

مکانیک git merge: جد مشترک، fast-forward، ادغام سه طرفه و merge commit — چه زمانی تاریخچه خطی می‌ماند و چه زمانی گره ادغام ساخته می‌شود؛ از Pro Git.

SE
Soheil Ebrahimpour

Founder & product engineer

·Sep 20, 2026·7 min read
اسکچ merge دو خط و استیکی Merge

Merge پاسخ به این مسئله است: دو خط توسعه از یک جد مشترک جدا شده‌اند و حالا باید یک تاریخچهٔ واحد قابل استفاده بسازیم. برخلاف کپی دستی فایل‌ها، Git با پیدا کردن ancestor مشترک و ترکیب تغییرات، سعی می‌کند نتیجه را خودکار بسازد. وقتی نتواند، Conflict می‌دهد (۲۰۷) — نه اینکه بی‌صدا یکی را overwrite کند.

مقالهٔ ۰۷۷ معرفی مفهومی داشت؛ اینجا مکانیک: fast-forward در برابر merge commit، ادغام سه طرفه، و پیامد هر کدام برای تاریخچه و PR.

fast-forward در برابر three-way merge

پاسخ کوتاه

git merge تغییرات یک Branch را وارد Branch جاری می‌کند. اگر Branch جاری جد مستقیم دیگری باشد، اغلب fast-forward رخ می‌دهد: فقط اشاره‌گر جلو می‌رود و Commit جدیدی لازم نیست. اگر هر دو طرف جلو رفته باشند، Git سه طرفه Merge می‌کند (پایه = جد مشترک، دو نوک) و معمولاً یک merge commit با دو والد می‌سازد مگر استراتژی/گزینهٔ دیگری بخواهید.

Merge تاریخچه را حفظ می‌کند که «این دو خط اینجا به هم رسیدند»؛ این آگاهی برای دیباگ گاهی از خطی بودن صرف باارزش‌تر است.

پیش‌نیاز ذهنی: جد مشترک

Git از روی گراف Commit نزدیک‌ترین جد مشترک (merge base) را پیدا می‌کند. تفاوت‌های هر سمت نسبت به آن پایه محاسبه می‌شود. اگر هر دو سمت یک ناحیهٔ یکسان را به شکل ناسازگار عوض کرده باشند، Conflict.

bash

git switch main git merge feature/x git log --oneline --graph --decorate -n 15

حالت ۱: Fast-forward

فرض: main روی C1 است؛ feature از C1 به C2 و C3 رسیده و main جلو نرفته. Merge feature به main می‌تواند اشاره‌گر main را به C3 حرکت دهد. تاریخچه خطی می‌ماند؛ merge commit ساخته نمی‌شود.

  • مزیت: ساده و خوانا.
  • محدودیت: رد پای «اینجا فیچر ادغام شد» به‌صورت Commit جدا نیست.
  • کنترل: --no-ff مجبور به ساخت merge commit می‌کند حتی وقتی fast-forward ممکن است — بعضی تیم‌ها برای ردیابی PR این را می‌خواهند.

حالت ۲: ادغام سه طرفه و merge commit

اگر main هم Commitهای جدید داشته باشد، fast-forward ممکن نیست. Git تغییرات دو سمت را نسبت به پایه ترکیب می‌کند. نتیجهٔ موفق یک Commit ادغام با دو والد است: یکی والدین main قبلی، یکی نوک feature.

استراتژی پیش‌فرض در عمل رایج ort/recursive برای دو سر است. موارد خاص (بیش از دو Branch) کمتر در روزمره لازم است.

جدول: انتخاب‌های Merge از دید تاریخچه

روشتاریخچهچه زمانی رایج است
Fast-forwardخطیBranch کوتاه، main ثابت مانده
Merge commit (--no-ff)گره ادغام واضحردیابی PR / فیچر
Squash merge (روی هاست)یک Commit روی هدفتاریخچهٔ main خلوت
Rebase سپس merge FFخطی‌شدهقبل از ادغام روی Branch خودتان

Squash روی GitHub یک Commit واحد از کل PR می‌سازد؛ از نظر Git محلی، جزئیات متفاوت است ولی هدف محصولی «main تمیز» است. مقایسهٔ عمیق‌تر با Rebase در ۲۱۱.

Merge محلی در برابر دکمهٔ Merge در Pull Request

روی GitHub سه حالت رایج: merge commit، squash، rebase-and-merge. هر کدام تاریخچهٔ main را differently شکل می‌دهند. قبل از انتخاب پیش‌فرض مخزن، با تیم توافق کنید؛ عوض کردن مداوم عادت Review را به هم می‌زند.

مستندات GitHub About pull request merges این گزینه‌ها را شرح می‌دهد. مهم: Rebase-and-merge روی هاست با git rebase محلی یکی نیست در جزئیات UX، ولی ایدهٔ خطی‌سازی مشترک است.

آماده‌سازی قبل از Merge

  1. Working tree تمیز یا Stash؛ Merge روی تغییرات کثیف هم‌پوشان ممکن است رد شود.
  2. تست و CI سبز روی PR.
  3. به‌روز بودن نسبی با پایه (main) برای کاهش Conflict.
  4. خواندن diff نهایی؛ Merge خودکار ≠ درست بودن محصول.

اشتباه‌های رایج

  • Merge کردن بدون دیدن --graph و فهمیدن fast-forward یا نه.
  • حل سرسری Conflict و Commit ادغام با پیام خالی.
  • Merge کردن Branch اشتباه به main به‌خاطر switch فراموش‌شده.
  • فرض اینکه Merge همیشه باید Rebase باشد یا برعکس — معیار تیم.

خواندن نتیجه با graph

بعد از هر ادغام غیرپیش‌پاافتاده، یک نگاه به گراف از ده پیام گنگ در چت مفیدتر است:

bash

git log --oneline --graph --decorate --all -n 20

Fast-forward را به‌صورت خط صاف می‌بینید؛ merge commit را به‌صورت گره با دو والد. این عادت هزینهٔ «پس الان روی کدام پایه هستیم؟» را کم می‌کند.

استراتژی و گزینه‌های کاربردی

  • git merge --ff-only: فقط اگر fast-forward ممکن باشد؛ وگرنه شکست — مفید برای سیاست خطی سخت.
  • git merge --no-ff: همیشه merge commit — ردیابی فیچر.
  • git merge --abort: خروج از ادغام ناتمام.
  • پیام Commit ادغام را خالی نگذارید اگر دلیل غیرعادی دارد (مثلاً revert نسبی).

جزئیات استراتژی‌های نادر (octopus و مانند آن) برای روزمره لازم نیست؛ اول توپولوژی دو سر را مسلط شوید.

Merge و CI: تعریف «سبز»

Merge موفق در Git فقط یعنی درخت فایل بدون Conflict ساخته شد. سبز بودن تست، امنیت وابستگی، و تأیید محصول لایه‌های بعدی‌اند. دکمهٔ Merge در PR باید پشت required checks باشد تا «ادغام متنی» با «قابل انتشار» یکی گرفته نشود.

Merge base را خودتان ببینید

bash

git merge-base main feature/x git log --oneline $(git merge-base main feature/x)..feature/x

دیدن بازهٔ Commitهایی که واقعاً وارد می‌شوند، قبل از Merge، غافلگیری Review را کم می‌کند. اگر بازه بیش از حد بزرگ است، قبل از ادغام به main روی شکستن PR فکر کنید.

Revert یک merge commit

برگرداندن merge commit با git revert -m نیاز به دانستن والد اصلی دارد. این عملیات پیشرفته‌تر از Revert ساده است؛ برای حادثهٔ Production گاهی لازم می‌شود. جزئیات undo در ۲۱۳؛ اینجا فقط بدانید merge commit ردپای قابل رجوع می‌سازد که یکی از دلایل ترجیح --no-ff در بعضی تیم‌هاست.

وقتی fast-forward نمی‌خواهید

بعضی تیم‌ها عمداً --no-ff می‌زنند تا هر فیچر یک گره ادغام داشته باشد و بتوان با git log --merges یا ابزار Release یادداشت ساخت. هزینه: تاریخچه کمی شلوغ‌تر. اگر squash را روی هاست انتخاب کنید، همان ردیابی را به صفحهٔ PR می‌سپارید نه به گراف Commit.

انتخاب بین این‌ها باید مکتوب باشد؛ تغییر هفته‌به‌هفته فقط ابزار را عوض می‌کند نه کیفیت را.

Merge از دید Incident

در حادثه، سؤال «کدام Merge این را آورد؟» با merge commit یا با لینک PR پاسخ داده می‌شود. اگر همه چیز squash شده و پیام‌ها مبهم باشند، پاسخ طولانی‌تر می‌شود. بنابراین حتی وقتی squash می‌کنید، پیام نهایی و لینک PR را جدی بگیرید — جزئی از مکانیک انسانی Merge است.

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

آیا merge commit زشت است؟

خیر؛ اطلاعات توپولوژی می‌دهد. اگر تیم تاریخچهٔ کاملاً خطی می‌خواهد، سیاست FF-only یا rebase را صریح کنید.

Abort چگونه است؟

اگر Merge ناتمام است: git merge --abort (در صورت مجاز بودن وضعیت). بعد از Commit ادغام، برگشت معمولاً با revert merge یا reset محتاطانه است — روی مشترکات خطرناک.

Merge از Remote؟

ابتدا Fetch، سپس merge origin/main (یا Pull). Pull فقط میان‌بر است؛ فهم جداگانهٔ Fetch و Merge کنترل بیشتری می‌دهد.

خلاصه

Merge با جد مشترک کار می‌کند: یا اشاره‌گر را fast-forward می‌کند یا نتیجهٔ سه طرفه را در merge commit می‌نشاند. انتخاب FF، --no-ff، squash یا مسیر rebase به اولویت خوانایی، ردیابی PR و عادت تیم بستگی دارد — مطلق «بهترین» وجود ندارد.

وقتی ترکیب خودکار شکست بخورد، سراغ ۲۰۷ بروید؛ برای جایگزینی خطی‌سازی سراغ ۲۱۰ و ۲۱۱.

منابع و مراجع

  • Pro Git — Basic Merging — https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging
  • git-merge documentation — https://git-scm.com/docs/git-merge
  • GitHub Docs — About pull request merges — https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges
  • Pro Git — Advanced Merging — https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging
  • git-merge-base documentation — https://git-scm.com/docs/git-merge-base

Author

SE

Soheil Ebrahimpour is the founder of FutureForge. He works on product design, architecture, and getting custom software into production.

Related notes

Related notes

Categories

Related services

From note to project

If this topic is close to your product or system, we can talk about the real scope.

If you are unsure about architecture or the build path, we can talk about the project.

Describe the problem and the constraints. If there is a fit, we will schedule a conversation.

git merge چگونه کار می‌کند
fast-forward
merge commit
three-way merge
recursive strategy
octopus
Soheil Ebrahimpour
Notes
Monolith در برابر Microservices: کدام را انتخاب کنیم؟
Logging چیست؟ ثبت رویداد برای تشخیص و پاسخ به حادثه
Empty State، Error State و Loading State چیست؟
UX مهم‌تر است یا UI؟
چرا متن بد می‌تواند حتی یک UI زیبا را خراب کند؟

Software architecture

Monolith در برابر Microservices: کدام را انتخاب کنیم؟

Sep 20, 2026

Operations

Logging چیست؟ ثبت رویداد برای تشخیص و پاسخ به حادثه

Sep 20, 2026

Product engineering

Empty State، Error State و Loading State چیست؟

Sep 20, 2026

Product engineering

UX مهم‌تر است یا UI؟

Sep 20, 2026

Product engineering

چرا متن بد می‌تواند حتی یک UI زیبا را خراب کند؟

Sep 20, 2026
All notes219
Software architecture13
Glossary37
Operations87
Product engineering74
Web guide8
Product engineering
Full-stack engineering
Engineering audit
Architecture consulting
Infrastructure and deployment
Discuss your project
Free tools
Discuss your project