GIT-MERGE-TREE(1) دستورات عمومی کاربر GIT-MERGE-TREE(1)

git-merge-tree - انجام ادغام بدون دستکاری ایندکس یا درخت کاری

git merge-tree [--write-tree] [<options>] <branch1> <branch2>
git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2> (منسوخ‌شده)

این دستور دارای یک حالت مدرن --write-tree و یک حالت منسوخ‌شده --trivial-merge است. به استثنای بخش «توضیحات منسوخ‌شده» در انتها، بقیه این مستندات حالت مدرن --write-tree را شرح می‌دهد.

یک ادغام را انجام می‌دهد، اما هیچ کامیت جدیدی ایجاد نمی‌کند و در درخت کاری یا ایندکس چیزی نمی‌خواند یا نمی‌نویسد.

ادغام انجام‌شده از همان قابلیت‌های دستور «واقعی» git-merge(1) استفاده خواهد کرد، از جمله:

•ادغام‌های سه‌طرفه محتوای فایل‌های جداگانه
•تشخیص تغییر نام
•مدیریت مناسب تداخل‌های پوشه/فایل
•تثبیت بازگشتی نیاکان (یعنی زمانی که بیش از یک پایه ادغام وجود دارد، ایجاد یک پایه ادغام مجازی با ادغام پایه‌های ادغام)
•و غیره.

پس از اتمام ادغام، یک شیء درخت ریشه (toplevel tree) جدید ایجاد می‌شود. برای جزئیات به بخش خروجی (OUTPUT) در زیر مراجعه کنید.

--stdin

خواندن کامیت‌های مورد نظر برای ادغام از ورودی استاندارد به‌جای خط فرمان. برای اطلاعات بیشتر به قالب ورودی در زیر مراجعه کنید. مستلزم -z است.

-z

عدم نقل‌قول نام فایل‌ها در بخش <اطلاعات فایل‌های متداخل>، و خاتمه دادن به هر نام فایل با یک نویسه NUL به‌جای خط جدید. همچنین شروع بخش پیام‌ها با یک نویسه NUL به‌جای خط جدید. برای اطلاعات بیشتر به خروجی در زیر مراجعه کنید.

--name-only

در بخش اطلاعات فایل‌های متداخل، به‌جای نوشتن فهرستی از چندتایی‌های (mode, oid, stage, path) در خروجی برای فایل‌های دارای تداخل، صرفاً فهرستی از نام‌های فایل‌های دارای تداخل را ارائه می‌دهد (و نام فایل‌ها را در صورت داشتن چندین مرحله متداخل، چند بار تکرار نمی‌کند).

--messages, --no-messages

نوشتن هرگونه پیام‌های اطلاع‌رسانی مانند "Auto-merging <path>" یا اعلان‌های CONFLICT در انتهای خروجی استاندارد (stdout). در صورت عدم تعیین، پیش‌فرض این است که این پیام‌ها در صورت وجود تداخل‌های ادغام گنجانده شوند و در غیر این صورت حذف گردند.

--quiet

غیرفعال کردن تمام خروجی‌های برنامه. زمانی مفید است که فقط به وضعیت خروج علاقه‌مند هستید. به merge-tree اجازه می‌دهد زمانی که تداخلی پیدا کرد زودتر خارج شود، و از نوشتن بیشتر اشیاء ایجادشده توسط ادغام‌ها جلوگیری کند.

--allow-unrelated-histories

دستور merge-tree به‌طور پیش‌فرض در صورتی که دو شاخه مشخص‌شده هیچ تاریخچه مشترکی نداشته باشند با خطا متوقف می‌شود. این فلگ می‌تواند برای نادیده گرفتن این بررسی و ادامه فرآیند ادغام در هر صورت استفاده شود.

--merge-base=<tree-ish>

به‌جای یافتن پایه‌های ادغام برای <branch1> و <branch2>، یک پایه ادغام را برای این ادغام مشخص می‌کند. این گزینه با --stdin ناسازگار است.

تعیین چندین پایه در حال حاضر پشتیبانی نمی‌شود، به این معنی که هنگام ادغام دو شاخه با بیش از یک پایه ادغام، استفاده از این گزینه ممکن است باعث شود نتایج ادغام با آنچه git merge محاسبه می‌کند متفاوت باشد. این می‌تواند شامل از دست رفتن احتمالی برخی از تغییرات ایجادشده در یک سمت از تاریخچه در ادغام نهایی باشد.

با این گزینه، از آنجا که پایه ادغام مستقیماً ارائه می‌شود، نیازی نیست <branch1> و <branch2> کامیت‌ها را مشخص کنند؛ درخت‌ها کافی هستند.

-X<option>, --strategy-option=<option>

ارسال گزینه مربوط به استراتژی ادغام به استراتژی ادغام مورد نظر. برای جزئیات به git-merge(1) مراجعه کنید.

برای یک ادغام موفق، خروجی git-merge-tree به سادگی یک خط است:

<OID of toplevel tree>

در حالی که برای یک ادغام دارای تداخل، خروجی به‌طور پیش‌فرض به این شکل است:

<OID of toplevel tree>
<Conflicted file info>
<Informational messages>

این موارد در ادامه به صورت جداگانه بررسی شده‌اند.

با این حال، یک استثنا وجود دارد. اگر --stdin ارسال شود، یک بخش اضافی در ابتدا و یک نویسه NUL در انتها وجود دارد و سپس تمام بخش‌ها برای هر خط از ورودی تکرار می‌شوند. بنابراین اگر ادغام اول دارای تداخل و دومی تمیز و بدون تداخل باشد، خروجی به این صورت خواهد بود:

<Merge status>
<OID of toplevel tree>
<Conflicted file info>
<Informational messages>
NUL
<Merge status>
<OID of toplevel tree>
NUL

این یک وضعیت عددی صحیح است که به دنبال آن یک نویسه NUL قرار دارد. این وضعیت صحیح عبارت است از:

0: merge had conflicts
1: merge was clean

این یک شیء درخت است که نشان‌دهنده آن چیزی است که در انتهای اجرای git merge در درخت کاری واکشی و مستقر می‌شد. اگر تداخل‌هایی وجود داشت، فایل‌های درون این درخت ممکن است حاوی نشانگرهای تداخل باشند. این بخش همیشه با یک خط جدید (یا در صورت ارسال -z با یک نویسه NUL) همراه است.

این دنباله‌ای از خطوط با قالب زیر است:

<mode> <object> <stage> <filename>

نام فایل همان‌طور که برای متغیر پیکربندی core.quotePath توضیح داده شده است، نقل‌قول (quote) خواهد شد (به git-config(1) مراجعه کنید). با این حال، اگر گزینه --name-only ارسال شود، مقادیر mode، object و stage حذف خواهند شد. اگر -z ارسال شود، «خطوط» به جای کاراکتر خط جدید، با یک نویسه NUL خاتمه می‌یابند.

این بخش پیام‌های اطلاع‌رسانی، معمولاً در مورد تداخل‌ها، ارائه می‌دهد. قالب این بخش بسته به ارسال یا عدم ارسال -z تفاوت چشمگیری دارد.

اگر -z ارسال شود:

قالب خروجی صفر یا چند رکورد اطلاعاتی تداخل است که هر کدام به این شکل هستند:

<list-of-paths><conflict-type>NUL<conflict-message>NUL

که در آن <list-of-paths> به این صورت است:

<number-of-paths>NUL<path1>NUL<path2>NUL...<pathN>NUL

و شامل مسیرها (یا نام شاخه‌ها) است که تحت تأثیر تداخل یا پیام اطلاع‌رسانی در <conflict-message> قرار گرفته‌اند. همچنین، <conflict-type> یک رشته پایدار است که نوع تداخل را توضیح می‌دهد، مانند:

•"Auto-merging"
•"CONFLICT (rename/delete)"
•"CONFLICT (submodule lacks merge base)"
•"CONFLICT (binary)"

و <conflict-message> یک پیام دقیق‌تر در مورد تداخل است که اغلب (اما نه همیشه) <stable-short-type-description> را در درون خود جای داده است. این رشته‌ها ممکن است در نسخه‌های آینده گیت تغییر کنند. چند مثال:

•"Auto-merging <file>"
•"CONFLICT (rename/delete): <oldfile> renamed...but deleted in..."
•"Failed to merge submodule <submodule> (no merge base)"
•"Warning: cannot merge binary files: <filename>"

اگر -z ارسال نشود:

این بخش با یک خط خالی شروع می‌شود تا آن را از بخش‌های قبلی جدا کند، و سپس فقط حاوی اطلاعات <conflict-message> از بخش پیشین است (که با خطوط جدید جدا شده‌اند). این‌ها رشته‌های ناپایداری هستند که نباید توسط اسکریپت‌ها تجزیه شوند و صرفاً برای خواندن کاربر انسانی در نظر گرفته شده‌اند. همچنین توجه داشته باشید که اگرچه رشته‌های <conflict-message> معمولاً حاوی خطوط جدید نیستند، اما گاهی اوقات خط جدید دارند. (با این حال، پیام‌های با قالب آزاد هرگز حاوی نویسه NUL نخواهند بود). بنابراین، کل این بلوک اطلاعاتی به عنوان مجموعه‌ای از تمام پیام‌های تداخل برای خوانندگان انسانی در نظر گرفته شده است.

برای یک ادغام موفق و بدون تداخل، وضعیت خروج 0 است. هنگامی که ادغام دارای تداخل باشد، وضعیت خروج 1 است. اگر ادغام به دلیل نوعی خطا قادر به اتمام (یا شروع) نباشد، وضعیت خروج چیزی غیر از 0 یا 1 خواهد بود (و خروجی نامشخص است). هنگامی که --stdin ارسال می‌شود، وضعیت بازگشتی برای هر دو ادغام موفق و متداخل برابر با 0 است، و اگر نتواند تمام ادغام‌های درخواستی را تکمیل کند، مقداری غیر از 0 یا 1 خواهد بود.

این دستور به عنوان یک ابزار لوله‌کشی سطح پایین (low-level plumbing) در نظر گرفته شده است، مشابه git-hash-object(1)، git-mktree(1)، git-commit-tree(1)، git-write-tree(1)، git-update-ref(1) و git-mktag(1). از این رو، می‌تواند به عنوان بخشی از یک سری مراحل مانند موارد زیر استفاده شود:

vi message.txt
BRANCH1=refs/heads/test
BRANCH2=main
NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) || {
    echo "There were conflicts..." 1>&2
    exit 1
}
NEWCOMMIT=$(git commit-tree $NEWTREE -F message.txt \
    -p $BRANCH1 -p $BRANCH2)
git update-ref $BRANCH1 $NEWCOMMIT

توجه داشته باشید که وقتی وضعیت خروج غیرصفر است، متغیر NEWTREE در این توالی شامل خروجی بسیار بیشتری نسبت به یک درخت خواهد بود.

برای تداخل‌ها، خروجی شامل همان اطلاعاتی است که با git-merge(1) دریافت می‌کنید:

•آنچه در درخت کاری نوشته می‌شد (شناسه OID درخت ریشه)
•مراحل مرتبه بالاتر که در ایندکس نوشته می‌شدند (اطلاعات فایل‌های متداخل)
•هر پیامی که در خروجی استاندارد چاپ می‌شد (پیام‌های اطلاع‌رسانی)

قالب ورودی git merge-tree --stdin کاملاً مبتنی بر متن است. هر خط دارای این قالب است:

[<base-commit> -- ]<branch1> <branch2>

اگر یک خط با -- جدا شده باشد، رشته قبل از جداکننده برای مشخص کردن یک پایه ادغام برای ادغام استفاده می‌شود و رشته پس از جداکننده شاخه‌هایی را که باید ادغام شوند توصیف می‌کند.

درخت ریشه حاصل را برای یافتن فایل‌های متداخل بررسی نکنید؛ در عوض بخش «اطلاعات فایل‌های متداخل» را بررسی و تجزیه کنید. نه‌تنها بررسی کل درخت در مخازن بزرگ بسیار کند خواهد بود، بلکه انواع بی‌شماری از تداخل‌ها وجود دارند که توسط نشانگرهای تداخل قابل نمایش نیستند (تغییر/حذف، تداخل حالت دسترسی، تغییر فایل باینری در هر دو طرف، تداخل‌های فایل/دایرکتوری، جایگشت‌های مختلف تداخل تغییر نام و غیره).

یک فهرست خالی از «اطلاعات فایل‌های متداخل» را به عنوان یک ادغام تمیز تفسیر نکنید؛ وضعیت خروج را بررسی کنید. یک ادغام می‌تواند بدون داشتن تداخل در تک‌تک فایل‌ها دارای تداخل باشد (چندین نوع تداخل تغییر نام دایرکتوری در این دسته قرار می‌گیرند و ممکن است موارد دیگری نیز در آینده اضافه شوند).

سعی نکنید انواع تداخل را از فهرست اطلاعات فایل‌های متداخل حدس بزنید یا کاربر را وادار به حدس زدن کنید. اطلاعات موجود در آنجا برای انجام این کار کافی نیست. برای مثال: تداخل‌های تغییر نام/تغییر نام (۱ به ۲) (هر دو طرف نام یک فایل را به گونه متفاوتی تغییر داده‌اند) منجر به داشتن سه فایل مختلف با مراحل مرتبه بالاتر می‌شود (اما هر کدام فقط یک مرحله مرتبه بالاتر دارند)، بدون اینکه هیچ راهی (به جز بخش پیام‌های اطلاع‌رسانی) برای تعیین اینکه کدام سه فایل به هم مرتبط هستند وجود داشته باشد. تداخل‌های فایل/دایرکتوری نیز منجر به فایلی با دقیقاً یک مرحله مرتبه بالاتر می‌شوند. تداخل‌های «احتمالاً درگیر در تغییر نام دایرکتوری» (زمانی که "merge.directoryRenames" تنظیم نشده یا روی "conflicts" تنظیم شده باشد) نیز به فایلی با دقیقاً یک مرحله مرتبه بالاتر منجر می‌شوند. در تمام این موارد، بخش پیام‌های اطلاع‌رسانی حاوی اطلاعات لازم است، اگرچه برای تجزیه ماشینی طراحی نشده است.

فرض نکنید که هر مسیر از اطلاعات فایل‌های متداخل و تداخل‌های منطقی در پیام‌های اطلاع‌رسانی نگاشت یک‌به‌یک دارند، و همچنین فرض نکنید که نگاشت یک‌به‌چند یا چندبه‌یک است. نگاشت‌های چندبه‌چند وجود دارند، به این معنی که هر مسیر می‌تواند در یک ادغام واحد چندین نوع تداخل منطقی داشته باشد، و هر نوع تداخل منطقی می‌تواند چندین مسیر را تحت تأثیر قرار دهد.

فرض نکنید که تمام نام‌های فایل فهرست‌شده در بخش پیام‌های اطلاع‌رسانی دارای تداخل بوده‌اند. ممکن است پیام‌هایی برای فایل‌هایی که هیچ تداخلی ندارند گنجانده شده باشد، مانند "Auto-merging <file>".

از برداشتن شناسه‌های OID از اطلاعات فایل‌های متداخل و ادغام مجدد آن‌ها برای نمایش تداخل‌ها به کاربر خودداری کنید. این کار باعث از دست رفتن اطلاعات می‌شود. در عوض، نسخه فایل موجود در شناسه OID درخت ریشه را بررسی کرده و آن را نمایش دهید. به‌ویژه دومی دارای نشانگرهای تداخلی خواهد بود که با شاخه/کامیت اصلی در حال ادغام و در صورت وجود تغییر نام، با نام فایل اصلی نشانه‌گذاری شده‌اند. در حالی که می‌توانید هنگام ادغام مجدد، شاخه/کامیت اصلی را در نشانه‌گذاری‌های نشانگر تداخل بگنجانید، نام فایل اصلی از اطلاعات فایل متداخل در دسترس نیست و بنابراین اطلاعاتی را که ممکن است به کاربر در حل تداخل کمک کند از دست خواهید داد.

مطابق با بخش توضیحات و بر خلاف بقیه این مستندات، این بخش حالت منسوخ‌شده --trivial-merge را شرح می‌دهد.

به جز گزینه اختیاری --trivial-merge، این حالت هیچ گزینه دیگری را نمی‌پذیرد.

این حالت سه شیء شبه‌درخت را می‌خواند و نتایج ادغام ساده (trivial merge) و مراحل متداخل را در خروجی استاندارد با قالبی شبیه به diff نمایش می‌دهد. از آنجا که این حالت برای اسکریپت‌های سطح بالاتر طراحی شده بود تا نتایج را دریافت کرده و به ایندکس بازگردانند، ورودی‌هایی را که با <branch1> مطابقت دارند حذف می‌کند. نتیجه این شکل دوم مشابه کاری است که ادغام سه‌طرفه git read-tree -m انجام می‌دهد، اما به‌جای ذخیره نتایج در ایندکس، دستور ورودی‌ها را در خروجی استاندارد چاپ می‌کند.

این شکل نه‌تنها کاربرد محدودی دارد (یک ادغام ساده نمی‌تواند ادغام محتوای فایل‌های جداگانه، تشخیص تغییر نام، مدیریت صحیح تداخل دایرکتوری/فایل و غیره را انجام دهد)، بلکه کار با قالب خروجی آن نیز دشوار است و به طور کلی حتی در ادغام‌های موفق عملکرد کمتری نسبت به شکل اول خواهد داشت (به‌ویژه هنگام کار در مخازن بزرگ).

بخشی از مجموعه git(1)

2026-06-29 Git 2.55.0