Cherry-pick — دستوری در Git است که تغییرات یک یا چند کامیت موجود را در شاخه فعلی اعمال میکند. برخلاف Merge (کل شاخه را منتقل میکند) و Rebase (دنبالهای از کامیتها را منتقل میکند)، cherry-pick فقط کامیتهای مشخصشده را انتخاب میکند. طبق git-scm.com، 2025، cherry-pick بیشتر در سناریوهای انتقال اصلاحات بین شاخههای انتشار مورد استفاده قرار میگیرد.
نکات اصلی
Cherry-pick — دستوری در Git است که تغییرات یک کامیت مشخص را کپی کرده و بهعنوان یک کامیت جدید در شاخه فعلی اعمال میکند. نام این دستور از استعاره «انتخاب گیلاس» گرفته شده: توسعهدهنده فقط کامیتهای مورد نیاز خود را انتخاب میکند و بقیه را نادیده میگیرد.
برخلاف Merge، cherry-pick یک کامیت ادغام ایجاد نمیکند و نیازی به ادغام کامل شاخهها ندارد. برخلاف Rebase، cherry-pick دنبالهای از کامیتها را منتقل نمیکند — فقط کامیتهای مشخصشده را جابجا میکند. این ویژگی cherry-pick را به ابزاری ایدهآل برای انتقال دقیق اصلاحات تبدیل میکند.
طبق دادههای Atlassian، 2025، cherry-pick در ۴۷٪ تیمهایی که همزمان با چندین شاخه انتشار کار میکنند استفاده میشود. cherry-pick بهویژه در توسعه موبایل که همزمان چندین نسخه از برنامه (انتشارهای LTS) پشتیبانی میشوند و نیاز به انتقال اصلاحات بین آنها وجود دارد، بسیار پرکاربرد است.
هنگام اجرای cherry-pick، Git diff بین کامیت مشخصشده و والد آن را محاسبه کرده و سپس این diff را در شاخه فعلی اعمال میکند. اگر تغییرات بدون تعارض اعمال شوند — Git یک کامیت جدید با همان پیام اما SHA جدید ایجاد میکند. اگر تعارض وجود داشته باشد — cherry-pick برای حل دستی متوقف میشود.
سینتکس cherry-pick ساده است: هش کامیتی را که میخواهید منتقل کنید مشخص کنید. Git تغییرات را بهعنوان یک کامیت جدید در شاخه فعلی کپی میکند. انتقال چندین کامیت به طور همزمان و همچنین محدودههای کامل پشتیبانی میشود.
# انتقال یک کامیت به شاخه فعلی
git cherry-pick a1b2c3d4
# انتقال چندین کامیت
git cherry-pick a1b2c3d4 e5f6g7h8
# انتقال محدوده کامیتها (از a1b2 تا f9e8، بدون احتساب a1b2)
git cherry-pick a1b2c3d4..f9e8d7c6
پس از اجرای cherry-pick، شاخه فعلی یک کامیت جدید با تغییرات کامیت اصلی دریافت میکند. پیام کامیت بهطور پیشفرض از کامیت اصلی کپی میشود، اما میتواند با پرچم -n (عدم ایجاد کامیت) یا --edit (ویرایش پیام) تغییر کند.
سناریوی معمول: در develop یک باگ بحرانی پیدا و رفع شده است که در شاخه انتشار release/v2.0 نیز وجود دارد. باید فقط این رفعباک را منتقل کرد، بدون اینکه کل develop را در شاخه انتشار ادغام کرد.
# هش کامیت با اصلاحیه در develop را پیدا کنید
git log --oneline develop
# a1b2c3d fix: null check in payment processing
# به شاخه انتشار سوئیچ کنید
git checkout release/v2.0
# اصلاحیه را اعمال کنید
git cherry-pick a1b2c3d4
# اگر تعارض وجود دارد — حل کنید و ادامه دهید
git add src/payment/PaymentProcessor.kt
git cherry-pick --continue
پرچم -x یک ارجاع به SHA اصلی در پیام کامیت اضافه میکند: «(cherry picked from commit a1b2c3d4)». این کار ردیابی مبدأ کامیت منتقلشده را آسانتر میکند. توصیه میشود از -x در همه سناریوها به جز پیشنویسهای موقت استفاده شود.
در صورت تعارض، cherry-pick مانند merge رفتار میکند: Git متوقف میشود و فایلهای دارای تعارض را علامتگذاری میکند. توسعهدهنده تعارض را حل میکند، git add را اجرا کرده و سپس git cherry-pick --continue را انجام میدهد. برای لغو — git cherry-pick --abort. پرچم --strategy به شما امکان میدهد استراتژی ادغام را مشخص کنید (مثلاً recursive با گزینهها).
# حل تعارض در cherry-pick
# Git فایلهای دارای تعارض را نشان میدهد
git status
# به صورت دستی حل کنید، سپس:
git add فایل_مجاز.kt
git cherry-pick --continue
# یا cherry-pick را لغو کنید:
git cherry-pick --abort
Cherry-pick در سناریوهایی بهینه است که نیاز به انتقال دقیق تغییرات بدون ادغام کل شاخهها وجود دارد. پنج مورد اصلی را بررسی میکنیم که در آنها cherry-pick بهترین انتخاب است.
برای توسعه موبایل، cherry-pick هنگام پشتیبانی از چندین نسخه برنامه حیاتی است. به عنوان مثال، اگر باگی در نسخه ۳.۲ که قبلاً در Google Play منتشر شده پیدا شود، در حالی که develop شامل کد نسخه ۴.۰ است — cherry-pick امکان انتقال اصلاحیه به شاخه v3.x را بدون ادغام تمام breaking changes فراهم میکند. این امر بهویژه برای پروژههایی که همزمان از دو یا چند نسخه اصلی با APIها و وابستگیهای متفاوت پشتیبانی میکنند بسیار مهم است.
مثال عملی: در یک برنامه موبایل، هنگام احراز هویت از طریق Google Sign-In در Android 12 یک crash کشف شد. اصلاحیه در develop انجام و بررسی شد. اما شاخه انتشار فعلی v2.5 در مرحله تست بتا است. Cherry-pick کامیت اصلاحیه از develop به release/v2.5 امکان گنجاندن اصلاحیه در انتشار بعدی را بدون انتقال بقیه تغییراتی که هنوز برای انتشار آماده نیستند فراهم میکند.
هنگام استفاده از cherry-pick در پروژههای موبایل مهم است که وابستگیها را در نظر بگیرید: اگر اصلاحیه فایلهایی را تحت تأثیر قرار دهد که در develop پس از نقطه انشعاب شاخه انتشار تغییر کردهاند، cherry-pick ممکن است مجموعه ناقصی از تغییرات را به همراه داشته باشد. در چنین مواردی باید بررسی کنید که همه تغییرات مرتبط نیز منتقل شدهاند، در غیر این صورت برنامه ممکن است ساخته نشود یا نادرست کار کند. همیشه پس از cherry-pick و قبل از push کردن تغییرات به شاخه مشترک، ساخت برنامه را بررسی کنید.
سه ابزار اصلی ادغام تغییرات در Git — merge، rebase و cherry-pick — وظایف متفاوتی را حل میکنند. انتخاب بستگی به این دارد که چه حجمی از تغییرات باید منتقل شود و تاریخچه چگونه باید باشد.
| معیار | Merge | Rebase | Cherry-pick |
|---|---|---|---|
| حجم | کل شاخه | دنباله کامیتها | کامیتهای انتخابشده |
| تاریخچه | انشعاب را حفظ میکند | خطی | خطی |
| کامیت Merge | بله (به جز ff) | خیر | خیر |
| خودکارسازی | کامل | به صورت زنجیرهای | فقط مشخصشده |
| برای شاخههای عمومی | ایمن | خطرناک | ایمن |
Merge — زمانی که باید دو شاخه را به طور کامل ادغام کرده و اطلاعات مربوط به انشعاب را حفظ کرد. Rebase — زمانی که باید یک شاخه شخصی را با تاریخچه تمیز به وضعیت فعلی بهروزرسانی کرد. Cherry-pick — زمانی که فقط یک کامیت یا چند کامیت انتخابشده مورد نیاز است.
در عمل، این ابزارها ترکیب میشوند: ویژگی با rebase دورهای روی develop توسعه داده میشود، سپس از طریق --no-ff merge ادغام میشود، و در صورت نیاز به انتقال اصلاحیه به شاخه دیگر از cherry-pick استفاده میشود. هر ابزار وظیفه خود را در مرحله خود حل میکند.
Cherry-pick — ابزاری مفید اما بالقوه خطرناک در صورت استفاده نادرست یا بیش از حد است. ریسکهای اصلی مربوط به تکرار کامیتها، از دست رفتن زمینه و تعارضات در ادغامهای بعدی است.
توصیهها برای به حداقل رساندن ریسکها: همیشه از پرچم -x برای مشخص کردن SHA اصلی استفاده کنید، دلیل cherry-pick را در پیام کامیت مستند کنید، و در صورت امکان از merge به جای cherry-pick استفاده کنید وقتی زمینه اجازه میدهد. اگر تعداد cherry-pickها زیاد است — بازسازی شاخهها را در نظر بگیرید.
خطوط لوله CI باید cherry-pick را به عنوان یک سناریوی جداگانه در نظر بگیرند. توصیه میشود یک بررسی خودکار راهاندازی کنید: هنگام ایجاد کامیت cherry-pick، CI بررسی میکند که فایلهای تغییر یافته با مجموعه مورد انتظار مطابقت داشته باشند و تستها را برای ماژولهای تحت تأثیر اجرا میکند. این کار ریسک بازگشت را در انتقال دقیق تغییرات بین شاخهها کاهش میدهد.
سوالات متداول
Cherry-pick تغییرات را از یک کامیت به شاخه دیگر منتقل میکند. Revert یک کامیت جدید ایجاد میکند که تغییرات کامیت مشخصشده را در همان شاخه لغو میکند. Revert تاریخچه را حذف نمیکند — یک تغییر معکوس اضافه میکند.
بله: git cherry-pick A B C — انتقال کامیتهای A، B و C به ترتیب. یا git cherry-pick A..C — انتقال همه کامیتها از A تا C (بدون احتساب A). ترتیب انتقال مطابق با ترتیب در دستور است.
به طور پیشفرض، cherry-pick روی کامیت merge کار نمیکند زیرا کامیت merge دو والد دارد. از پرچم -m 1 استفاده کنید تا مشخص کنید با کدام والد مقایسه شود. -m 1 diff را نسبت به والد اول در نظر میگیرد.
لغو cherry-pick از طریق git reset --hard HEAD~1 امکانپذیر است، اگر این آخرین کامیت باشد. اگر کامیت قبلاً push شده است — از git revert <SHA> برای ایجاد یک کامیت معکوس استفاده کنید.
بیمعنی است، اما از نظر فنی امکانپذیر است. اگر کامیت از قبل در شاخه وجود داشته باشد، Git تشخیص میدهد که تغییرات قبلاً اعمال شدهاند و اعلام میکند: «The previous cherry-pick is now empty, possibly due to conflict resolution.» کامیت دوباره ایجاد نخواهد شد.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید