Cherry-pick — یک دستور Git است که تغییرات حاصل از کمیت مشخصشده را در شاخه فعلی اعمال میکند، بدون انتقال کل تاریخ شاخه مبدا. به عکس merge یا rebase، cherry-pick با هر کمیت بهصورت جداگانه کار میکند: توسعهدهنده کمیت مورد نظر را بر اساس هش انتخاب میکند و تنها تغییرات آن را منتقل میکند. به استناد به مستندات Git (2026)، cherry-pick بهویژه برای انتقال نقطهای اصلاحات در شاخههای انتشاراتی مفید است، زمانی که merge کامل ضروری نیست یا میتواند پرخطر باشد. دستور یک کمیت جدید با هش جدید ایجاد میکند، اما پیام اصلی و نویسنده را حفظ میکند.
نکات کلیدی
Cherry-pick — دستور git cherry-pick است که تغییرات یک کمیت موجود را گرفته و آنها را به عنوان یک کمیت جدید در شاخه فعلی اعمال میکند. کمیت اصلی در شاخه خود بدون تغییر باقی میماند، و در شاخه مقصد یک کپی از تغییرات ایجاد میشود. این دستور زمانی مفید است که بدون انتقال کل شاخه، یک اصلاح مشخص را انتقال دهید.
نحوه نگارش: git cherry-pick <commit-hash>. Git تفاوت (diff) کمیت مشخص را با والدش تحلیل کرده و این تفاوت را به شاخه فعلی اعمال میکند. اگر تغییرات چند فایل باشند — همه با هم انتقال مییابند. دستور همچنین محدوده را میپذیرد: git cherry-pick A..B — همه کمیتها از A تا B، بدون A.
فلگها قابلیتها را گسترش میدهند: -n (--no-commit) تغییرات را بدون ایجاد کمیت به پوشه کاری و اندیس اعمال میکند — زمانی که بخواهید تغییرات چند کمیت را در یکی ترکیب کنید مفید است. فلگ -x خط (cherry picked from commit ...) را به پیام کمیت اضافه میکند که پیگیری منشا تغییرات را در تاریخ آسانتر میکند.
# چری-پیک یک کمیت با هش
git cherry-pick a1b2c3d
# چری-پیک چند کمیت (بهترتیب)
git cherry-pick a1b2c3d e4f5g6h i6j7k8l
# چری-پیک بدون اتوماتیک کمیت
git cherry-pick -n a1b2c3d
# فلگ -x ارجاعی به کمیت اصلی اضافه میکند
git cherry-pick -x a1b2c3d
سناریو اصلی — انتقال اصلاحات در شاخههای انتشاراتی. تصور کنید: در develop یک باگ حراج پیدا و برطرف شده است. شاخه انتشاراتی release/v2.1 قبلاً جدا شده و این باگ در آن نیز وجود دارد. Merge کامل develop به release کدهای ناتمام زیادی را منتقل میکند، در حالی که cherry-pick یک کمیت با رفع باگ یک راهحل ایمن و دقیق است.
سناریو دوم — لغو تغییرات (revert) با بازگرداندن بعدی. اگر یک کمیت با git revert لغو شده و سپس مشخص شود که لغو اشتباه بوده — cherry-pick کمیت لغوشده تغییرات را بازمیگرداند. این از لغوی revert کورکتر است چون تعارضات تکراری ایجاد نمیکند.
سناریو سوم — ترکیب کمیتها از شاخههای feature مختلف در یک شاخه آزمایشی برای آزمون انتگراسیون. به جای ادغام چند شاخه ناتمام (با کدهای ناتمام)، میتوان تنها کمیتهای آماده از هر شاخه را انتخاب کرده و کار مشترک آنها را آزمود.
Cherry-pick با rebase و merge از آن نحو متفاوت است که در سطح کمیتهای جداگانه کار میکند، نه کل شاخهها. در حالی که rebase همه کمیتهای شاخه را منتقل میکند و merge دو شاخه را ادغام میکند، cherry-pick تنها مورد نیاز را انتخاب میکند. این آن را به ابزاری دقیقتر تبدیل میکند، اما بیشتر دستی است.
تفاوت دیگر — نویسندگی. در cherry-pick، Git بهطور پیشفرض نویسنده کمیت اصلی (Author) را حفظ میکند، اما کمیتکننده (Committer) کاربر فعلی خواهد بود. در پیام کمیت میتوان منشا را از طریق فلگ -x پیگیری کرد. در rebase، هم نویسنده و هم کمیتکننده — هر دو کاربر فعلی با هش جدید خواهند بود.
عملکرد: cherry-pick یک کمیت سریعتر از merge دو شاخه با تعداد زیاد کمیت انجام میشود. اما اگر بخواهید دهها کمیت را منتقل کنید، ایجاد یک شاخه موقت و اجرای rebase کارآمدتر خواهد بود و نیازی به مشخص کردن دهها هش ندارد.
| عملیات | حوزه کاربرد | عوارض جانبی |
|---|---|---|
| Cherry-pick | کمیتهای جداگانه | هش جدید، تکرار کد |
| Rebase | همه کمیتهای شاخه | بازنویسی تاریخ، هشهای جدید |
| Merge | ادغام کامل شاخهها | Merge-commit، حفظ تاریخ |
چند کمیت را میتوان با یک دستور با فهرست هشهای جداشده با فاصله انتقال داد: git cherry-pick A B C. Git کمیتها را بهترتیب در طول اعمال میکند. اگر کمیتی باعث تعارض شود، cherry-pick متوقف شده و توسعهدهنده باید تعارض را حل کرده، سپس با git cherry-pick --continue ادامه دهد.
محدوده کمیتها: git cherry-pick A..B (همه کمیتهای بعد از A تا B، بدون A) و git cherry-pick A^..B (همه کمیتها از A شامل شده تا B). محدودهها زمانی مفیدند که بخواهید همه کمیتهای یک شاخه را بدون ارتباط والدی منتقل کنید — مثلاً در انتقال ویژگی آماده از شاخه قدیمی به جدید.
فلگ --strategy تعیین میکند که Git چگونه تغییرات را اعمال کند. بهطور پیشفرض از راهبرد recursive استفاده میشود، اما میتوان ours یا theirs را برای انتخاب خودکار طرف تعارض مشخص کرد. فلگ --mainline در cherry-pick merge-commit استفاده میشود — شماره والد (1 یا 2) را مشخص میکند که diff نسبت به آن محاسبه میشود.
# محدوده کمیت چری-پیک
git cherry-pick develop~5..develop~2
# چری-پیک کمیت merge (مشخص کردن والد)
git cherry-pick -m 1 m9n0o1p
# استفاده از راهبرد theirs
git cherry-pick --strategy=recursive \
--strategy-option=theirs a1b2c3d
# ادامه پس از حل تعارض
git cherry-pick --continue
تعارضات در cherry-pick زمانی ایجاد میشوند که تغییرات کمیت منتقلشونده به همان خطوطی برخورد کنند که در شاخه مقصد تغییر کردهاند. Git اجرا را متوقف کرده، فایلهای متعارض را علامتگذاری کرده و منتظر حل میماند. در وضعیت، چنین فایلهایی به عنوان both modified نمایش داده میشوند.
ترتیب اقدام در تعارض: فایل متعارض را باز کنید، نشانگرهای تعارض را پیدا کنید (<<<<<<<، =======، >>>>>>>)، محتوا را ویرایش کنید، نشانگرها را حذف کنید، git add را برای فایلهای حلشده اجرا کرده و git cherry-pick --continue را بزنید. اگر تعارض قابل حل نباشد — git cherry-pick --abort کل cherry-pick را لغو کرده، شاخه را به وضعیت اولیه بازمیگرداند.
مشکل رایج: کمیت قبلاً حاوی تغییراتی معادل با موجود است. در این صورت Git در طول اعمال cherry-pick «nothing to commit» یا «empty commit» گزارش میدهد. فلگهای --keep-redundant-commits و --empty=keep Git را مجبور به ایجاد کمیت خالی برای حفظ تسلسل میکنند، و --skip امکان عدم توجه به چنین کمیتی را میدهد.
# تعارض در طول cherry-pick — توقف
git cherry-pick a1b2c3d
# خطا: نمیتوان a1b2c3d... را اعمال کرد پیام کمیت
# حل تعارض → افزودن به اندیس
git add src/conflicted_file.swift
git cherry-pick --continue
# عدم توجه به کمیت خالی (قبلاً اعمال شده)
git cherry-pick --skip
# لغو کامل
git cherry-pick --abort
قاعده اول: همیشه بررسی کنید که کمیت منتقلشونده خودکفا است. اگر کمیت A به تغییرات کمیت B وابسته است که منتقل نمیشود، cherry-pick A میتواند کامپایل را بشکند. قبل از cherry-pick با git show --stat <hash> بررسی کنید که کمیت چه فایلهایی را تغییر داده است.
قاعده دوم: cherry-pick را مستند کنید. از فلگ -x استفاده کنید تا در پیام کمیت ارجاعی به کمیت مبدا حفظ شود. این در تحلیل بعدی تاریخ کمک میکند تا منشا تغییر را بفهمید. بدون -x، cherry-pick مانند یک کمیت عادی به نظر میرسد و منشای آن تنها از طریق git log --graph قابل تعیین است.
قاعده سوم: از cherry-pick بین شاخههایی که بسیار از هم دور شدهاند خودداری کنید. اگر از زمان ایجاد کمیت زمان زیادی گذشته و بیز کد بهطور چشمگیری تغییر کرده است، تعارضات چندگانه و پیچیده خواهند بود. در چنین مواردی، اصلاح را در شاخه مقصد از نو انجام دهید — این کار از حل دهها تعارض زمان کمتری میگیرد.
سوالات متداول
کردن چری-پیک — اعمال تغییرات یک کمیت مشخص در شاخه فعلی از طریق git cherry-pick. دستور یک کمیت جدید با همان تغییرات اما با هش جدید ایجاد میکند. کمیت اصلی در شاخه خود دستنخورده باقی میماند. این یک الترناتیو برای ادغام کامل یک شاخه است زمانی که تنها یک کمیت مشخص مورد نیاز است.
Cherry-pick انتخاب میشود زمانی که بدون انتقال کل شاخه، یک یا چند کمیت مشخص را منتقل کنید. Merge برای ادغام کامل شاخهها استفاده میشود. سناریو معمولی cherry-pick — انتقال hotfix از شاخه توسعه به شاخه انتشاراتی است که در آن سایر تغییرات هنوز آماده نیستند.
قبل از اتمام — git cherry-pick --abort عملیات را کاملاً لغو میکند. پس از اتمام موفقیتآمیز — git revert <hash> یک کمیت ایجاد میکند که تغییرات cherry-pick را لغو میکند. تفاوت با --abort: revert کمیت را از تاریخ حذف نمیکند، بلکه یک کمیت جدید لغوکننده ایجاد میکند.
کمیت خالی زمانی ایجاد میشود که تغییرات از قبل در شاخه مقصد وجود داشته باشند. از git cherry-pick --skip برای عدم توجه به چنین کمیتی استفاده کنید، یا git cherry-pick --keep-redundant-commits برای حفظ تسلسل هشها یک کمیت خالی ایجاد کنید.
Cherry-pick کمیتهای انتخابی (یکی یا چندتایی) را به شاخه فعلی منتقل میکند. Rebase همه کمیتهای شاخه را به یک بنیان جدید منتقل میکند. Cherry-pick شاخه مبدا را تغییر نمیدهد، rebase تاریخ را بازنویسی میکند. Cherry-pick دقیق اما دستی است؛ rebase خودکار اما برای شاخههای عمومی خطرناک است.
نتایج
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.