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 من قبل 47% من الفرق التي تعمل مع عدة فروع إصدار في وقت واحد. Cherry-pick مطلوب بشكل خاص في تطوير التطبيقات المحمولة، حيث يتم دعم عدة إصدارات من التطبيق (إصدارات LTS) في وقت واحد ويتطلب نقل الإصلاحات بينها.
عند تنفيذ cherry-pick، يحسب Git الفرق بين الالتزام المحدد والأصل، ثم يطبق هذا الفرق على الفرع الحالي. إذا تم تطبيق التغييرات بدون تعارض — ينشئ Git التزامًا جديدًا بنفس الرسالة ولكن بتجزئة جديدة. إذا كان هناك تعارض — يتوقف 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 مهم بشكل حاسم عند دعم إصدارات متعددة من التطبيق. على سبيل المثال، إذا تم العثور على خطأ في الإصدار 3.2 المنشور بالفعل على Google Play، ويحتوي develop على شيفرة للإصدار 4.0 — يسمح cherry-pick بنقل الإصلاح إلى فرع v3.x دون دمج جميع التغييرات الجذرية. هذا مهم بشكل خاص للمشاريع التي يتم فيها دعم إصدارين رئيسيين أو أكثر بواجهات برمجة تطبيقات وتبعيات مختلفة في وقت واحد.
مثال عملي: في تطبيق محمول، تم اكتشاف عطل أثناء تسجيل الدخول عبر Google Sign-In على Android 12. تم إجراء الإصلاح في develop واجتاز مراجعة الشيفرة. ومع ذلك، فإن فرع الإصدار الحالي v2.5 موجود بالفعل في مرحلة اختبار بيتا. يسمح Cherry-pick لتزام الإصلاح من develop إلى release/v2.5 بتضمين الإصلاح في الإصدار القادم دون نقل التغييرات الأخرى التي ليست جاهزة بعد للإصدار.
عند استخدام cherry-pick في المشاريع المحمولة، من المهم مراعاة التبعيات: إذا كان الإصلاح يؤثر على الملفات التي تم تغييرها في develop بعد نقطة انحراف فرع الإصدار، فقد يجلب cherry-pick مجموعة غير كاملة من التغييرات. في مثل هذه الحالات، من الضروري التحقق من أن جميع التغييرات ذات الصلة قد تم نقلها أيضًا، وإلا قد لا يتم تجميع التطبيق أو يعمل بشكل غير صحيح. تحقق دائمًا من البناء بعد cherry-pick قبل دفع التغييرات إلى الفرع المشترك.
الأدوات الرئيسية الثلاث لدمج التغييرات في Git — merge و rebase و cherry-pick — تحل مهامًا مختلفة. يعتمد الاختيار على مقدار التغيير الذي يجب نقله وكيف يجب أن يبدو التاريخ.
| المعيار | Merge | Rebase | Cherry-pick |
|---|---|---|---|
| النطاق | الفرع بأكمله | سلسلة من الالتزامات | التزامات محددة |
| التاريخ | يحافظ على التفرع | خطي | خطي |
| التزام الدمج | نعم (باستثناء ff) | لا | لا |
| الأتمتة | كاملة | بالسلسلة | فقط المحددة |
| للفروع العامة | آمن | خطير | آمن |
Merge — عندما تحتاج إلى دمج فرعين بالكامل والحفاظ على معلومات التفرع. Rebase — عندما تحتاج إلى تحديث فرع شخصي إلى أحدث حالة بسجل نظيف. Cherry-pick — عندما تحتاج فقط إلى التزام واحد أو عدة التزامات محددة.
في الممارسة العملية، يتم دمج هذه الأدوات: يتم تطوير الميزة مع rebase دوري على develop، ثم يتم دمجها عبر --no-ff merge، وعند الحاجة لنقل إصلاح إلى فرع آخر، يتم استخدام cherry-pick. كل أداة تحل مهمتها في مرحلتها الخاصة.
Cherry-pick — أداة مفيدة ولكنها قد تكون خطيرة عند استخدامها بشكل غير صحيح أو مفرط. ترتبط المخاطر الرئيسية بتكرار الالتزامات وفقدان السياق والتعارضات أثناء عمليات الدمج اللاحقة.
توصيات لتقليل المخاطر: استخدم دائمًا العلامة -x للإشارة إلى SHA الأصلي، وقم بتوثيق سبب cherry-pick في رسالة الالتزام، وعند الإمكان استخدم merge بدلاً من cherry-pick عندما يسمح السياق بذلك. إذا أصبح عدد cherry-picks كبيرًا — فكر في إعادة هيكلة الفروع.
خطوط أنابيب 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 لتزام الدمج لا يعمل لأن التزام الدمج له أصلان. استخدم العلامة -m 1 لتحديد أي أصل للمقارنة. -m 1 يأخذ الفرق بالنسبة للأصل الأول.
إلغاء cherry-pick عبر git reset --hard HEAD~1 إذا كان هذا هو آخر التزام. إذا تم دفع الالتزام بالفعل — استخدم git revert <SHA> لإنشاء التزام إلغاء.
لا فائدة، لكنه ممكن تقنيًا. إذا كان الالتزام موجودًا بالفعل في الفرع، سيكتشف Git أن التغييرات مطبقة بالفعل ويبلغ: «The previous cherry-pick is now empty, possibly due to conflict resolution.» لن يتم إنشاء الالتزام مرة أخرى.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا