■ مساحة · مسار النثر
git cherry-pick <sha> ينسخ التزاماً واحداً — الرقعة نفسها، SHA جديد، لا يتحرك شيء.
المدى يستثني بدايته: A^..B يشمل A, A..B يتخطاه بصمت.
توقف عند تعارض؟ حُلّه، ثم git add, git cherry-pick --continue — وحتى ذلك الحين أنت في منتصف التسلسل.
النسخة، مرسومة
إصلاح يعيش في فرع feature؛ وmain يحتاجه الآن. الـ pick يعيد تشغيل الرقعة، ويسكّ SHA جديداً، ويترك الأصل في مكانه تماماً:
شكل — نسخ لا نقل: احذف فرع feature متى شئت؛ فالنسخة المقطوفة لها SHA خاص ولا تعتمد على القديم
الخطوات الثلاث
جد SHA، وبدّل إلى الفرع الهدف، وقطف — فهبوطه حيث يشير HEAD:
# 1. locate the commit on the source branch
git log feature/payment-fix --oneline -5
# 2. switch to the branch that should receive it
git switch main
# 3. copy it over
git cherry-pick 1a2b3c4
verify: git log -1 --stat → التغيير المقطوف، SHA جديد، على الفرع الهدف
راحتان تستحقان المعرفة: git cherry-pick <branch> يقطف طرف tip ذلك الفرع — مفيد، لكن يسهل الوقوع فيه بالخطأ معتقداً صورة قديمة لما هو «tip». وبعد أي قطف، يؤكد git log -1 --stat ما هبط: ثانية قراءة، توفّر عليك revert.
التزامات متعددة
ثلاث صيغ، بترتيب شيوع الحاجة إليها — كلها تعمل عبر الفروع، لأن الـ SHA تُحلّ على المستودع كله:
# 1. explicit list — picked in the order you list them
git cherry-pick 1a2b3c4 5d6e7f8
# 2. range — everything after A up to and including B
git cherry-pick A..B
# 3. range including A
git cherry-pick A^..B
verify: git log --oneline -4 بعد القطف → الالتزان معاد تشغيلهما بالترتيب، والأقدم أولاً
التمييز بين A..B وA^..B هو المفاجأة الكلاسيكية: A..B يستثني A. تخيّل المدى ابتداءً من git log، وقِطف oldest..newest، فتتخطى الأقدم التزاماً بصمت — oldest^..newest يزيل خلاف الواحد. لطيّ عدة قطفات في التزام واحد بدل ثلاثة، ضعها في stage من دون التزام عبر -n / --no-commit، ثم التزام واحد:
git cherry-pick -n 1a2b3c4 5d6e7f8
git commit -m "Backport: payment retry fixes"
«لماذا لا يعمل» — الأسباب الأربعة
- تعارضٌ أوقف القطف. يطبّق git الرقعة، فيصطدم بسطر تغيّر في الفرعين معاً، فيتوقف في منتصف التسلسل. حُلّ الملفات، ثم
git add <resolved-files>وgit cherry-pick --continue— أو--abortللعودة إلى حالة ما قبل القطف.--continueليس اختيارياً ولا مفهوماً ضمنياً: إلى أن تشغّله،git statusيستمر في القول: You are currently cherry-picking. - القطف فارغ (رسالة «The previous cherry-pick is now empty») — التغيير موجود أصلاً في هذا الفرع، غالباً من قطف سابق أو من merge مضغوط. تجاوزه عبر
git cherry-pick --skip، أو فرض علامة فراغ عبر--allow-empty. - الالتزام هو التزام merge. للالتزام المدمج ودانان، فقول «طبّق هذا الفرق» غامض — لذا يرفض git بدل أن يخمّن. قل أي ودان رقّقت مقابله:
git cherry-pick -m 1 <merge-sha>وترقَّم الوالدان بترتيب تسجيلهما: parent 1 هو الفرع الذي كنت عليه لحظة merge، وparent 2 هو الفرع القادم —-m 1هو غالباً ما يريده backport. - شجرة عمل خاطئة أو HEAD منفصلة. هبوط القطف حيث يشير HEAD.
git branch --show-currentقبل القطف؛ فإن لم يطبع شيئاً فأنت في وضع HEAD المنفصلة، وسيصبح الالتزام يتيماً بمجرد التبديل.
PICK VS MERGE VS REBASE
| الأمر | ما يهبط على الهدف | التاريخ | متى تستخدمه |
|---|---|---|---|
git cherry-pick <sha> | التزامات مسمّاة فقط | نسخة، SHA جديدة | إصلاح بعينه يلزم أن ينتقل الآن |
git merge <branch> | كل ما في الفرع | التزام merge أو fast-forward | تريد الفرع كله، والانفراع مرئياً |
git rebase <base> | كل التزامات الفرع، معاد تشغيلها | خطي، SHA أعيد كتابتها | تريد الفرع شريطاً خطياً نظيفاً |
git revert <sha> | نقيض التزام | يضيف التزام undo | التزام هبط يلزم التراجع عنه على تاريخ مشترك |
القاعدة في سطر واحد: cherry-pick ينقل اختياراً واحداً؛ وmerge وrebase ينقلان كل شيء. مدُّ اليد نحو cherry-pick بوصفه «مزامنة» مع فرع علامة على أنك تريده merge فعلاً. عادة تستحق التجنب قطف الالتزام نفسه إلى فروع عدّة على المدى الطويل — فكل إصلاح قادم في الفرع المصدر يوجب قطفاً جديداً، وقد تتباعد الفروع في نهاية الأمر. عمليات backport إلى فروع release نمط طبيعي؛ أما كون موازٍ دائم فليس كذلك.
سير العمل، مكثّفاً
git log <source-branch> --oneline -5 # find the SHA(s)
git switch <target-branch> # land in the right place
git cherry-pick A^..B # range, list, or single SHA
# on conflict: resolve → git add → git cherry-pick --continue
git log -1 --stat # confirm what landed
جدِّ، بدِّل، قِطْفْ، تحقّق. للأمر سمعة خطر لا يستحقها — فالفرق إما أن يُطبّق أو يتوقف ويخبرك بالسبب. الخطأ الوحيد المدمّر فعلاً هو القطف في فرع خاطئ، وgit log -1 قبل الدفع يجعل هذا الخطأ يصعب أن يتسلّل.
A..B تستثني A)، وسلوك القطف الفارغ، و-m ترقيم الودان، هي سلوك موثق لـ git، مكتوبة من قطفات هبطت فعلاً.نهاية صفحة القطف · لم يُجلب شيء · كل شيء محلي