git cherry-pick — boshqa branch dan bitta commit olish

~15 daq · Git · Git Tarixini Boshqarish

Muammodan boshlaylik

feature/yangi-dizayn branch ida 15 ta commit. Ulardan biri — 7-chisi — dizaynga umuman aloqasi yo'q: siz ish davomida topgan xavfsizlik xatosini tuzatgansiz. Bu tuzatish production ga hozir kerak.

Lekin butun branch ni merge qilib bo'lmaydi — dizayn hali tayyor emas, qolgan 14 commit production ga chiqmasligi kerak.

Kerak — faqat bitta commitni olish. Bu — cherry-pick ("olchani terib olish").


Asosiy foydalanish

git log feature/yangi-dizayn --oneline
f6a7b8c Dizayn: footer
e5f6a7b Dizayn: header animatsiyasi
d4e5f6a Login: SQL injection zaifligi tuzatildi    ← kerakli
c3d4e5f Dizayn: ranglar palitrasi
...
git switch main
git cherry-pick d4e5f6a
[main 9a8b7c6] Login: SQL injection zaifligi tuzatildi
 Date: Fri Nov 6 11:20:05 2026 +0500
 1 file changed, 3 insertions(+), 2 deletions(-)
 Oldin:
  main               ●────●────●
                           \
  feature/yangi-dizayn      ●──●──D──●──●

 Keyin:
  main               ●────●────●────D'      ← D ning nusxasi
                           \
  feature/yangi-dizayn      ●──●──D──●──●

D' — D ning o'zgarishlari bilan yangi commit (yangi hash, xuddi rebase dagidek — 17-dars). Muallif va xabar saqlanadi.


Foydali bayroqlar

git cherry-pick -x d4e5f6a

-x — xabarga manba qo'shiladi:

Login: SQL injection zaifligi tuzatildi

(cherry picked from commit d4e5f6a2b1c...)

Keyinchalik "bu tuzatish qayerdan kelgan?" savoliga javob. Ommaviy branch lar orasida cherry-pick qilganda — doim -x.

git cherry-pick A B C              # bir nechta, ketma-ket
git cherry-pick A^..C              # A dan C gacha (A ham kiradi)
git cherry-pick -n d4e5f6a         # commit qilmasdan — faqat o'zgarishlarni staging ga
git cherry-pick -e d4e5f6a         # xabarni tahrirlash imkoniyati bilan

Conflict

Commit boshqa kontekstga ko'chirilyapti — o'sha qatorlar main da boshqacha bo'lishi mumkin:

CONFLICT (content): Merge conflict in src/login.js
error: could not apply d4e5f6a... Login: SQL injection zaifligi tuzatildi

Odatdagidek (16-dars):

# tahrirlash → git add src/login.js
git cherry-pick --continue
# yoki
git cherry-pick --skip     # bu commit ni o'tkazib yuborish (bir nechta bo'lsa)
git cherry-pick --abort    # hammasini bekor qilish

Tipik holatlar

1. Hotfix ni bir nechta versiyaga

Siz ikkita versiyani qo'llab-quvvatlaysiz: main (v3) va release/2.x (eski mijozlar uchun). Xavfsizlik tuzatishi main ga tushdi — uni v2 ga ham kerak:

git switch release/2.x
git cherry-pick -x 9a8b7c6
git push

Bu — cherry-pick ning eng to'g'ri va keng tarqalgan foydalanishi.

2. Noto'g'ri branch ga commit

feature/savat ga commit qilmoqchi edingiz, lekin feature/qidiruv da ekansiz (va ikkalasi push qilingan, reset noqulay):

git switch feature/savat
git cherry-pick e5f6a7b              # to'g'ri joyga nusxa
git switch feature/qidiruv
git revert e5f6a7b                   # yoki lokal bo'lsa: git reset --hard HEAD~1

3. Tashlab ketilgan branch dan foydali narsa

Eski tajriba branch ida bitta yaxshi yordamchi funksiya bor edi — qolgani keraksiz:

git cherry-pick 7c8d9e0

Qachon cherry-pick qilmaslik kerak

[!WARNING] Cherry-pick — istisno, odatiy ish usuli emas. Uni branch larni sinxronlash uchun muntazam ishlatsangiz — tarix bir xil o'zgarishning ko'plab nusxalari bilan to'ladi (D, D', D''...), va keyingi merge larda Git ularni bir xil deb tanimasligi va keraksiz conflict lar keltirishi mumkin.

Vaziyat To'g'ri vosita
Butun branch kerak merge yoki rebase
main dagi yangiliklarni feature ga olish git merge main / git rebase main
Bitta tuzatishni boshqa versiya branch iga ✅ cherry-pick -x
Branch dagi 15 commitdan 12 tasi kerak Branch ni qayta tashkil qilish (rebase -i), keyin merge

Yaxshiroq odat: xavfsizlik tuzatishini darhol alohida branch da main dan boshlab qilish (fix/sql-injection), keyin u main ga ham, kerak bo'lsa feature branch ga ham merge qilinadi. Cherry-pick — "boshqacha qilish kerak edi" holatlarni tuzatish uchun.


Nima uchun shunday?

Nima uchun cherry-pick commitni "nusxalaydi" — uni bir branch dan boshqasiga shunchaki "ko'chira" olmaydimi?

Chunki commit — o'zgarish emas, surat (1-dars), va u o'z otasiga bog'langan. D commit i feature/yangi-dizayn ning tarixida, o'z ota-onalari bilan yashaydi. Uni main ga qo'yish uchun Git D va uning otasi orasidagi farqni (diff) hisoblaydi va uni main ning oxiriga qo'llaydi — natijada boshqa otaga ega, demak boshqa hash li yangi commit. Asl D joyida qoladi. Shuning uchun -x muhim: Git o'zi D va D' orasida bog'lanishni saqlamaydi — bu bog'lanishni faqat xabardagi izoh eslab qoladi.


Xulosa

Eslab qoling:

  • git cherry-pick <commit> — boshqa branch dan bitta commit o'zgarishlarini joriy branch ga
  • Natija — yangi commit (yangi hash), asl joyida qoladi
  • -x — manbani xabarga yozish; ommaviy branch larda doim
  • A B C, A^..C — bir nechta; -n — commit qilmasdan
  • Conflict: --continue, --skip, --abort
  • Eng yaxshi foydalanish: hotfix ni eski versiya branch lariga
  • Muntazam sinxronlash uchun emas — merge / rebase ishlating

Keyingi dars

30-dars: git bisect — xatoni qaysi commitda paydo bo'lganini topish