IlmHamroh
JavaScript Full-stack/7-qism. Git va GitHub asoslari21/36-dars19 daqiqa
Mundarija (34)

Git cherry-pick: bitta commitni boshqa branchga ko'chirish

Qisqacha: git cherry-pick <sha> boshqa branchdagi bitta commitning o'zgarishini olib, joriy branchga yangi commit qilib qo'shadi. Butun branchni birlashtirish shart emas — faqat kerakli tuzatish ko'chadi. Yangi commit boshqa SHA oladi; -x unga "qayerdan olingan" degan izoh yozadi. Butun branch kerak bo'lsa — cherry-pick emas, merge.

Bu darsda

  • Boshqa branchdagi bitta commitni git cherry-pick bilan joriy branchga ko'chira olasiz.
  • Nega ko'chirilgan commit yangi SHA olishini va -x nima uchun kerakligini tushuntira olasiz.
  • Bir nechta commitni oraliq (A..B) bilan va --no-commit bilan bitta commitga yig'ib ko'chirasiz.
  • Cherry-pick conflictini --continue, --skip va --abort bilan boshqarasiz.
  • Cherry-pick qachon to'g'ri va qachon merge yaxshiroq ekanini ajrata olasiz.

Oldin bilishingiz kerak: Merge: fast-forward va uch tomonlama birlashtirish, Conflictlarni yechish amaliyoti, Xatoni tuzatish 2: reset va revert.

1. Nega bu kerak?

Oldingi darsda shoshilinch tuzatishni stash yordamida main da qildik. Lekin ba'zan tuzatish allaqachon boshqa branchda yozilgan bo'ladi.

«Bahor» saytida shunday bo'ldi. Aziz bosh sahifaga ish vaqtini yozdi va adashdi: 7:00–32:00. Soat 32 bo'lmaydi — to'g'risi 7:00–23:00. Bu main ga tushib ketdi.

Keyin Aziz feature/yangi-dizayn branchida ishlay boshladi. U yerda yangi ranglar, tugma stili, menyuga yangi narxlar — va yo'l-yo'lakay ish vaqtidagi xatoni ham tuzatdi. Branch hali tayyor emas: dizaynni Jasur aka ko'rib chiqmagan.

Jasur aka esa aytadi: "Dizayn kutsin. Lekin saytda 32:00 turibdi — mehmonlar kulyapti. Shuni hoziroq tuzating."

Merge qilsak — tugallanmagan dizayn ham main ga tushadi. Qo'lda qaytadan yozsak — bir xil ishni ikki marta qilamiz va xato qilishimiz mumkin. To'g'ri yo'l — faqat o'sha bitta commitni ko'chirish.

Cherry-pick (cherry-pick) — boshqa branchdagi tanlangan commitning o'zgarishini olib, joriy branchga yangi commit sifatida qo'shish. Inglizcha nomi "gilos terish" degani: daraxtdagi hamma gilosni emas, eng pishganini tanlab uzasiz. Bozorda ham shunday — butun yashikni olmasdan, kerakli uch-to'rtta olmani tanlab olasiz.

2. Birinchi cherry-pick

2.1 Qaysi commit kerak?

Avval feature/yangi-dizayn da main da yo'q commitlarni ko'ramiz. main..feature/yangi-dizayn — "feature/yangi-dizayn da bor, main da yo'q" (O'zgarishlarni ko'rish darsidagi ikki nuqta):

bash
git log --oneline main..feature/yangi-dizayn
text
9cdfd83 (HEAD -> feature/yangi-dizayn) Menyu: chuchvara narxini qo'sh
ce3e988 Menyu: manti narxini qo'sh
1f75118 Dizayn: tugma rangini qo'sh
95ff9a5 Bosh sahifa: ish vaqtidagi xatoni tuzat
c1da4fa Dizayn: yashil rangni qo'sh

Beshta commit. Bizga faqat bittasi kerak — 95ff9a5. Bu yerda Yaxshi commit darsidagi qoida o'z foydasini ko'rsatyapti: har commit bitta ish qilgan. Agar Aziz tuzatishni dizayn bilan bitta commitga qo'shganda edi, uni alohida ajratib bo'lmasdi.

Siz ham o'z tarixingizda shunday ro'yxat ko'rasiz, lekin SHA'lar boshqacha bo'ladi. Buyruqlarda o'z SHA'ingizni yozing.

main ga o'tib, holatni tekshiramiz:

bash
git switch main
cat index.html
text
<h1>Bahor choyxonasi</h1>
<a href="aloqa/">Aloqa</a>
<p>Ish vaqti: 7:00–32:00</p>

(switch chiqishini tashlab ketdik.) Xato shu yerda.

2.2 git cherry-pick <sha>

bash
git cherry-pick 95ff9a5
text
[main 7804fbf] Bosh sahifa: ish vaqtidagi xatoni tuzat
 Date: Tue Oct 6 10:10:00 2026 +0500
 1 file changed, 1 insertion(+), 1 deletion(-)

Natija oddiy commit natijasiga o'xshaydi, bitta farqi bor — Date: qatori. Uni pastda tushuntiramiz. Avval faylga qaraymiz:

bash
cat index.html
git log --oneline -3
text
<h1>Bahor choyxonasi</h1>
<a href="aloqa/">Aloqa</a>
<p>Ish vaqti: 7:00–23:00</p>
7804fbf (HEAD -> main) Bosh sahifa: ish vaqtidagi xatoni tuzat
062f2de Bosh sahifa: ish vaqtini qo'sh
07b061d Menyu: lag'mon narxini qo'sh

Xato tuzaldi. main da yangi commit paydo bo'ldi — aynan o'sha xabar bilan. Dizayn va menyu commitlari esa feature/yangi-dizayn da joyida qoldi.

gitGraph
  commit id: "062f2de ish vaqti"
  branch feature/yangi-dizayn
  commit id: "c1da4fa rang"
  commit id: "95ff9a5 tuzatish"
  commit id: "1f75118 tugma"
  checkout main
  commit id: "7804fbf tuzatish"
  checkout feature/yangi-dizayn
  commit id: "ce3e988 manti"
  commit id: "9cdfd83 chuchvara"

Nimaga qarang: main ga "tuzatish" nomli commit qo'shildi, lekin u feature/yangi-dizayn dagi commitga chiziq bilan ulanmagan. Bu ikkita alohida commit — bittasining nusxasi.

2.3 Nega SHA boshqacha?

Ikkala commitni topamiz:

bash
git log --oneline --all --grep="ish vaqtidagi"
text
7804fbf (HEAD -> main) Bosh sahifa: ish vaqtidagi xatoni tuzat
95ff9a5 Bosh sahifa: ish vaqtidagi xatoni tuzat

Xabar bir xil, o'zgarish bir xil, SHA har xil. Nega?

Git ichkaridan darsida ko'rgansiz: commit SHA'si uning butun mazmunidan hisoblanadi — surat, muallif, sana, xabar va ota commit. 95ff9a5 ning otasi — c1da4fa (yashil rang). Yangi commitning otasi esa 062f2de — main ning uchi. Ota boshqa — demak, SHA ham boshqa.

Shuning uchun "commitni ko'chirish" so'zi biroz aldamchi. Cherry-pick commitni ko'chirmaydi. U o'zgarishni — "qaysi qator qanday o'zgargani"ni — oladi va shu o'zgarish bilan yangi commit yaratadi. Asl commit joyida qoladi.

2.4 Date: qatori — muallif va commit qiluvchi

Ikkala commitni to'liq ko'ramiz:

bash
git show --stat HEAD
text
commit 7804fbf17451d7414a9b11b800d6be637d5b05c3 (HEAD -> main)
Author: Aziz Karimov <aziz@example.com>
Date:   Tue Oct 6 10:10:00 2026 +0500

    Bosh sahifa: ish vaqtidagi xatoni tuzat

 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Date — 10:10, asl commit yozilgan vaqt. Biz esa cherry-pick'ni 11:00 da qildik. Git har commitda ikki odamni yozadi:

  • Author (muallif) — o'zgarishni kim va qachon yozgani. Cherry-pick uni asl commitdan oladi.
  • Committer (commit qiluvchi) — commitni kim va qachon shu tarixga qo'ygani. U yangi.

git log odatda muallif sanasini ko'rsatadi. Cherry-pick natijasidagi Date: qatori ham shuni eslatadi: "bu o'zgarish aslida boshqa vaqtda yozilgan". Jamoada bu muhim — hamkasbingizning tuzatishini siz ko'chirsangiz, muallif baribir u bo'lib qoladi.

Tekshirib ko'ring: Aziz bitta commitni ikki xil branchga cherry-pick qildi. Tarixda nechta commit bo'ladi va ularning SHA'lari bir xilmi?

Javob

Uchta: asl commit va ikkita nusxa. Uchalasining SHA'si har xil, chunki har birining ota commiti boshqa. Xabar va o'zgarish esa bir xil.

3. -x: qayerdan olinganini yozib qo'yish

3.1 Muammo: nusxa izsiz

Uch oydan keyin kimdir main dagi 7804fbf ga qaraydi. U bu tuzatish boshqa branchdan olinganini bilmaydi. feature/yangi-dizayn birlashtirilganda tarixda bir xil xabarli ikki commit ko'rinadi — "nega ikki marta?" degan savol tug'iladi.

-x flagi bu savolga javobni commit xabarining o'ziga yozadi. Sinash uchun oldingi cherry-pick'ni bekor qilamiz (reset — commit hali hech kimga yuborilmagan, bu xavfsiz):

bash
git reset --hard HEAD~1
git cherry-pick -x 95ff9a5
text
HEAD is now at 062f2de Bosh sahifa: ish vaqtini qo'sh
[main 0efd6c3] Bosh sahifa: ish vaqtidagi xatoni tuzat
 Date: Tue Oct 6 10:10:00 2026 +0500
 1 file changed, 1 insertion(+), 1 deletion(-)

SHA yana boshqa — 0efd6c3, chunki xabar o'zgardi. To'liq xabarni ko'ramiz:

bash
git log -1
text
commit 0efd6c33899b91568dbcadbd54c33cdb3b43e1c9 (HEAD -> main)
Author: Aziz Karimov <aziz@example.com>
Date:   Tue Oct 6 10:10:00 2026 +0500

    Bosh sahifa: ish vaqtidagi xatoni tuzat
    
    (cherry picked from commit 95ff9a5f84921405a3dfe8447121ddc1b2c39e63)

Xabar oxiriga qator qo'shildi. Tarjimasi: "95ff9a5... commitidan cherry-pick qilingan". Endi har kim asl commitni topa oladi.

3.2 Qachon -x ishlatiladi?

Git hujjati tavsiyasi aniq: asl commit boshqalar ko'ra oladigan branchda bo'lsa — -x qo'ying. Masalan, main dagi tuzatishni eski versiya branchiga ko'chirganda. Asl commit faqat sizning lokal, keyin o'chiriladigan branchingizda bo'lsa, havola foydasiz — u SHA hech qayerda topilmaydi.

Asl commit qayerda -x
Umumiy branchda (main, reliz branchi) ha
Faqat lokal, o'chiriladigan branchda shart emas

4. Bir nechta commit

4.1 Oraliq: A..B

Jasur aka menyu narxlarini ham kutib o'tirmaslikka qaror qildi. Kerakli ikki commit — ce3e988 (manti) va 9cdfd83 (chuchvara) — ketma-ket turibdi. Ularni bitta buyruq bilan olish mumkin:

bash
git cherry-pick 1f75118..9cdfd83
text
[main 3dc511a] Menyu: manti narxini qo'sh
 Date: Tue Oct 6 10:30:00 2026 +0500
 1 file changed, 1 insertion(+)
[main 4f88651] Menyu: chuchvara narxini qo'sh
 Date: Tue Oct 6 10:40:00 2026 +0500
 1 file changed, 1 insertion(+)

Diqqat qiling: oraliq 1f75118 dan boshlanadi — manti commitidan oldingi commitdan. A..B — "A dan keyingi, B gacha, B ham kiradi". A ning o'zi kirmaydi. Bu git log main..feature/yangi-dizayn dagi ikki nuqtaning xuddi o'zi.

Birinchi commitni ham qo'shish uchun uning otasini ko'rsatish kerak. Bunda Tarixni o'qish darsidagi ^ qo'l keladi: git cherry-pick ce3e988^..9cdfd83 ham aynan shu ikki commitni oladi. Ketma-ket bo'lmagan commitlarni esa probel bilan sanab chiqasiz: git cherry-pick c1da4fa 1f75118.

bash
git log --oneline -4
text
4f88651 (HEAD -> main) Menyu: chuchvara narxini qo'sh
3dc511a Menyu: manti narxini qo'sh
0efd6c3 Bosh sahifa: ish vaqtidagi xatoni tuzat
062f2de Bosh sahifa: ish vaqtini qo'sh

Ikki yangi commit, tartib saqlangan.

Tekshirib ko'ring: feature/yangi-dizayn da commitlar ketma-ketligi: c1da4fa, 95ff9a5, 1f75118. git cherry-pick c1da4fa..1f75118 nechta commit ko'chiradi?

Javob

Ikkita: 95ff9a5 va 1f75118. Oraliqning boshi (c1da4fa) kirmaydi. Uchalasini olish uchun c1da4fa^..1f75118.

4.2 --no-commit: bir nechtasini bitta commitga

Dizayn ham tayyor bo'ldi, lekin ikki kichik commit — "yashil rang" va "tugma rangi" — main da bitta commit bo'lsa, tarix tozaroq. -n (--no-commit) o'zgarishlarni qo'llaydi, lekin commit qilmaydi — faqat qutiga soladi:

bash
git cherry-pick -n c1da4fa 1f75118
git status -s
text
M  assets/css/asosiy.css

M chap ustunda — o'zgarish qutida (Uch hudud). Nima tushganini tekshiramiz:

bash
git diff --staged
text
diff --git a/assets/css/asosiy.css b/assets/css/asosiy.css
index 693ce9b..7aaec3e 100644
--- a/assets/css/asosiy.css
+++ b/assets/css/asosiy.css
@@ -1 +1,3 @@
 body { font-family: sans-serif; }
+:root { --rang: green; }
+button { background: var(--rang); }

Ikkala commitning o'zgarishi birga. Endi o'zimiz commit qilamiz:

bash
git commit -m "Dizayn: yashil rang va tugmani qo'sh"
text
[main 9973d9e] Dizayn: yashil rang va tugmani qo'sh
 1 file changed, 2 insertions(+)

--no-commit yana bir holatda qulay: ko'chirishdan oldin o'zgarishni ko'rib, biror qatorini tuzatib olmoqchi bo'lsangiz.

4.3 Qaysilari allaqachon olingan? git cherry

Bir necha cherry-pick'dan keyin chalkashish oson: feature/yangi-dizayn dagi qaysi commitlar main da allaqachon bor? SHA'lar farq qilgani uchun git log bu savolga javob bermaydi. Buning uchun alohida, kam ma'lum buyruq bor — git cherry (oxirida -pick yo'q):

bash
git cherry -v main feature/yangi-dizayn
text
+ c1da4faba048ac14989c5128638bd1d722200628 Dizayn: yashil rangni qo'sh
- 95ff9a5f84921405a3dfe8447121ddc1b2c39e63 Bosh sahifa: ish vaqtidagi xatoni tuzat
+ 1f75118cfe854f4f939e4565f8eae1c438430b64 Dizayn: tugma rangini qo'sh
- ce3e988fafc46ce5b8572d5b23aaf282a68c6eb8 Menyu: manti narxini qo'sh
- 9cdfd8357db2718923e74044b5266278d9436a95 Menyu: chuchvara narxini qo'sh

git cherry SHA'larni emas, o'zgarishning o'zini solishtiradi. - — "bu o'zgarish main da allaqachon bor". + — "hali yo'q". -v esa commit xabarini ham qo'shadi.

Qiziq joyi — dizayn commitlari + bilan chiqdi. Biz ularni-ku oldik! Lekin ikkalasini bitta commitga birlashtirdik. Birlashgan o'zgarish alohida-alohida o'zgarishlarning hech biriga to'liq teng emas, shuning uchun Git ularni tanimadi. --no-commit ning narxi shu: kuzatish qiyinlashadi.

5. Cherry-pick conflicti

5.1 Conflict qanday chiqadi

Cherry-pick o'zgarishni "yamoq" kabi qo'llaydi — stash kabi. Yamoq yangi joyga mos kelmasa — conflict. Buni ko'rish uchun --no-commit dan oldingi holatga qaytib sinab ko'rdik: main da yashil rang hali yo'q edi va Aziz faqat "tugma rangi" commitini olmoqchi bo'ldi:

bash
git cherry-pick 1f75118
text
Auto-merging assets/css/asosiy.css
CONFLICT (content): Merge conflict in assets/css/asosiy.css
error: could not apply 1f75118... Dizayn: tugma rangini qo'sh
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
hint: Disable this message with "git config set advice.mergeConflict false"

Tarjimasi: "1f75118 ni qo'llab bo'lmadi. Conflictlarni yechgach, ularni git add bilan belgilang va git cherry-pick --continue ni ishga tushiring. Buning o'rniga shu commitni --skip bilan tashlab ketishingiz mumkin. Hammasini bekor qilib, cherry-pick'dan oldingi holatga qaytish uchun — --abort." Oxirgi hint shu maslahatni o'chirish yo'lini aytadi (bu yangi git config set shakli — Git'ni sozlash darsidagi jadvalda).

Nega conflict? "Tugma rangi" commiti --rang o'zgaruvchisini ishlatadi va u "yashil rang" commitidan keyingi qatorga yozilgan. main da bu qator yo'q — yamoqning "qo'shni qatorlari" mos kelmadi. Faylda:

text
body { font-family: sans-serif; }
<<<<<<< HEAD
=======
:root { --rang: green; }
button { background: var(--rang); }
>>>>>>> 1f75118 (Dizayn: tugma rangini qo'sh)

Markerlar Conflictlarni yechish darsidan tanish. HEAD tomoni bo'sh, pastki tomonda esa commit nomi turibdi. Git bizga aslida muhim narsani ko'rsatyapti: bu commit o'zidan oldingi commitga bog'liq.

5.2 Uch chiqish yo'li

git status ham shu yo'llarni aytadi:

text
On branch main
You are currently cherry-picking commit 1f75118.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   assets/css/asosiy.css
Buyruq Qachon
--continue Conflictni yechdingiz va git add qildingiz — davom etish
--skip Bu commit kerak emas — tashlab, keyingisiga o'tish
--abort Hammasini bekor qilib, boshlang'ich holatga qaytish

--continue dan keyin Git commit xabarini tahrirlash uchun muharrirni ochadi — xabar tayyor, saqlab yopsangiz yetarli.

Bizning holatda to'g'ri qaror — bekor qilish va ikkala dizayn commitini birga olish (xuddi yuqoridagi --no-commit misolidagidek):

bash
git cherry-pick --abort
git status -s
git log --oneline -1
text
4f88651 (HEAD -> main) Menyu: chuchvara narxini qo'sh

status -s bo'sh, tarix cherry-pick'dan oldingi joyida. Hech narsa buzilmadi.

5.3 Bo'sh cherry-pick

Allaqachon olingan commitni yana olsangiz nima bo'ladi? Birinchi cherry-pick'dan keyin sinab ko'rdik:

bash
git cherry-pick 95ff9a5
text
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

Otherwise, please use 'git cherry-pick --skip'
...

Tarjimasi: "Cherry-pick bo'sh chiqdi, ehtimol conflict yechimi sababli. Baribir commit qilmoqchi bo'lsangiz — git commit --allow-empty. Aks holda git cherry-pick --skip ni ishlating." (... — git status qismi, yuqoridagi kabi.) O'zgarish allaqachon main da bor — qo'shadigan narsa yo'q. To'g'ri javob — git cherry-pick --skip. Bo'sh commit tarixga foyda bermaydi.

6. Qachon cherry-pick ishlatmaslik kerak

6.1 Butun branch kerak bo'lsa — merge

Aziz barcha besh commitni cherry-pick bilan olishi mumkin edi. Lekin bu yomon fikr. Keyin feature/yangi-dizayn baribir main ga birlashtiriladi. Nima bo'lishini sinab ko'rdik — cherry-pick qilingan main dan vaqtinchalik branch ochib, feature/yangi-dizayn ni merge qildik:

text
*   2d25120 (HEAD -> feature/merge-sinov) Merge branch 'feature/yangi-dizayn'
|\  
| * 9cdfd83 (feature/yangi-dizayn) Menyu: chuchvara narxini qo'sh
| * ce3e988 Menyu: manti narxini qo'sh
| * 1f75118 Dizayn: tugma rangini qo'sh
| * 95ff9a5 Bosh sahifa: ish vaqtidagi xatoni tuzat
| * c1da4fa Dizayn: yashil rangni qo'sh
* | 9973d9e (main) Dizayn: yashil rang va tugmani qo'sh
* | 4f88651 Menyu: chuchvara narxini qo'sh
* | 3dc511a Menyu: manti narxini qo'sh
* | 0efd6c3 Bosh sahifa: ish vaqtidagi xatoni tuzat
|/  
* 062f2de Bosh sahifa: ish vaqtini qo'sh
* 07b061d Menyu: lag'mon narxini qo'sh

(Bu git log --oneline --graph ning chiqishi.) Merge conflictsiz o'tdi — o'zgarishlar bir xil bo'lgani uchun Git ularni birlashtira oldi. Lekin tarixga qarang: "manti narxi", "chuchvara narxi", "ish vaqtidagi xato" — har biri ikki marta. O'qiyotgan odam chalkashadi: qaysi biri haqiqiy?

Bu safar conflict bo'lmadi, lekin har doim ham shunday emas. Nusxa ko'chirilgandan keyin ikkala branchda o'sha qatorlar yana o'zgartirilsa, merge paytida conflict chiqishi mumkin.

6.2 Qoida

  • Bitta-ikkita alohida commit kerak (tuzatish, kichik qo'shimcha) — cherry-pick.
  • Butun branch yoki uning katta qismi kerak — merge (Merge) yoki rebase (Rebase).
  • Commit o'zidan oldingilariga bog'liq («Cherry-pick conflicti» bo'limidagi "tugma rangi" kabi) — yoki bog'liqlarini ham birga oling, yoki branchni kutib turing.

Maslahat: Tuzatishni dastlab qayerda qilish kerak? Eng yaxshi tartib — tuzatishni avval main da (yoki undan ochilgan alohida fix/... branchida) qilish, keyin kerakli joylarga ko'chirish. Aziz tuzatishni dizayn branchiga "yo'l-yo'lakay" qo'shgani uchun cherry-pick kerak bo'ldi. Ba'zan bu muqarrar, lekin rejalashtirish osonroq.

Tekshirib ko'ring: Hamkasbingiz profil branchida 12 ta commit qildi. Sizga ulardan 11 tasi kerak. Cherry-pick bilan 11 tasini olasizmi?

Javob

Yo'q. Deyarli butun branch kerak — merge qilish yaxshiroq. Keraksiz bitta commitni oldin profil branchida bekor qilish mumkin (masalan revert bilan). 11 ta cherry-pick tarixda 11 ta dublikat qoldiradi va keyingi birlashtirishni chalkashtiradi.

7. Ko'p uchraydigan xatolar

7.1 Noto'g'ri SHA yoki branch nomi

bash
git cherry-pick abc1234
git cherry-pick feature/yangi-dezayn
text
fatal: bad revision 'abc1234'
fatal: bad revision 'feature/yangi-dezayn'

Tarjimasi: "halokatli xato: noto'g'ri reviziya". Reviziya (revision) — Git'da commitni ko'rsatadigan har qanday nom: SHA, branch, HEAD~2. Birinchisida bunday SHA yo'q (ko'chirishda xato yoki boshqa repodagi SHA). Ikkinchisida branch nomi xato yozilgan — dezayn. Tuzatish: SHA'ni git log --oneline --all dan nusxalang. Diqqat: branch nomini yozsangiz, cherry-pick shu branchning faqat oxirgi commitini oladi, butun branchni emas.

7.2 Cherry-pick yarim yo'lda qolgan

Conflictdan keyin boshqa ish bilan chalg'ib ketdingiz. Ertasi kuni git status yozsangiz, You are currently cherry-picking commit ... qatori chiqadi. Bu — cherry-pick hali tugamagan degani. Yangi ishni boshlashdan oldin uni --continue yoki --abort bilan yakunlang.

7.3 Merge commitni cherry-pick qilish

Merge commitning ikki otasi bor (Merge). Yuqoridagi vaqtinchalik branchdagi merge commitni main ga olishga urinib ko'rdik:

bash
git cherry-pick 2d25120
text
error: commit 2d25120b2072a5c6f74480da4d2e574cd5701beb is a merge but no -m option was given.
fatal: cherry-pick failed

Tarjimasi: "xato: bu commit merge, lekin -m flagi berilmagan. Cherry-pick muvaffaqiyatsiz." Git qaysi ota bilan solishtirishni bilmaydi. -m 1 bilan birinchi otani tanlash mumkin — xuddi revert -m 1 kabi. Lekin bu kamdan-kam kerak: butun merge'ni ko'chirishdan ko'ra, branchni birlashtirish odatda to'g'riroq.

7.4 Push qilingan commitni "ko'chirib, o'chirish"

Ba'zilar commitni boshqa branchga cherry-pick qilib, keyin asl branchdan reset bilan o'chiradi. Commit hali hech kimga yuborilmagan bo'lsa — mumkin (Reflog va favqulodda yordam darsidagi "noto'g'ri branchga commit" retsepti). Allaqachon GitHub'ga yuborilgan bo'lsa — rebase oltin qoidasi amal qiladi: umumiy tarixni qayta yozmang.

8. Mashqlar

1-mashq (oson): Nechta commit?

log natijasi (yuqoridan pastga — yangidan eskiga): e5, d4, c3, b2, a1. Har buyruq nechta commit ko'chiradi?

  1. git cherry-pick c3
  2. git cherry-pick b2..d4
  3. git cherry-pick b2^..d4
  4. git cherry-pick a1 e5
Yechim
  1. Bitta — c3.
  2. Ikkita — c3 va d4 (boshi b2 kirmaydi).
  3. Uchta — b2, c3, d4 (b2^ — a1, oraliq undan keyin boshlanadi).
  4. Ikkita — a1 va e5, probel bilan sanalgan.

2-mashq (o'rta): Bo'sh joylarni to'ldiring

«Bahor» main branchiga feature/yangi-dizayn dagi ish vaqti tuzatishini, qayerdan olinganini yozib, ko'chiring:

bash
git switch 
git log --oneline main..feature/yangi-dizayn
git cherry-pick  95ff9a5
git log -1

Ishora: avval tuzatish tushadigan branchga o'tiladi; qayerdan olinganini yozadigan flag — «-x: qayerdan olinganini yozib qo'yish» bo'limida.

Yechim
bash
git switch main
git log --oneline main..feature/yangi-dizayn
git cherry-pick -x 95ff9a5
git log -1

git log -1 xabar oxirida (cherry picked from commit 95ff9a5...) qatorini ko'rsatadi. Sizning SHA'ingiz boshqa — o'zingizning log chiqishidan oling.

3-mashq (qiyin): Qaysi yo'l to'g'ri?

Har vaziyat uchun — cherry-pick, merge yoki boshqa yo'l? Nega?

  1. tolov branchida 8 commit, hammasi tayyor va review'dan o'tgan. Ularni main ga qo'shish kerak.
  2. tolov branchidagi bitta commit main dagi xavfsizlik xatosini tuzatadi. Qolgan 7 tasi hali tayyor emas.
  3. Aziz c3 ni cherry-pick qildi — conflict chiqdi. Qarasa, c3 o'zidan oldingi b2 da yaratilgan faylni o'zgartiradi, main da esa bu fayl yo'q.
  4. Aziz main dagi tuzatishni -x bilan eski reliz-1 branchiga ko'chirdi. Keyin uni yana bir marta, adashib, ko'chirmoqchi bo'ldi.

Ishora: «Qachon cherry-pick ishlatmaslik kerak» bo'limidagi qoida, «Cherry-pick conflicti» dagi uch yo'l va «Bo'sh cherry-pick».

Yechim
  1. Merge. Butun branch tayyor — cherry-pick 8 ta dublikat yaratadi.
  2. Cherry-pick (umumiy branchdan olingani uchun -x bilan). Bitta mustaqil tuzatish — aynan shu holat uchun.
  3. --abort, keyin git cherry-pick b2 c3 (yoki b2^..c3) — bog'liq commit bilan birga. Yoki b2 ham kerak emasligini hisobga olib, branch tayyor bo'lishini kutish.
  4. Git The previous cherry-pick is now empty deydi — o'zgarish allaqachon bor. git cherry-pick --skip bilan chiqib ketadi. Bo'sh commit kerak emas.

4-mashq: Portfolio qadami — tajribadan tuzatishni olish

Portfolio'ingizda tajriba branchini oching. Unda ikki commit qiling: biri "Haqimda" sahifasi matnini sinov uchun o'zgartirsin (hali tayyor emas), ikkinchisi bosh sahifadagi haqiqiy xatoni tuzatsin (masalan, havola matnidagi imlo xatosi). Keyin faqat tuzatishni main ga oling.

  1. tajriba branchida ikki commitni yarating. git log --oneline main..tajriba bilan ikkalasini ko'ring.
  2. main ga o'ting va tuzatish commitini -x bilan cherry-pick qiling.
  3. git log --oneline va git log -1 --format=%B bilan tekshiring. %B — faqat commit xabarining o'zini chiqaradi.
Yechim
bash
cd ~/kurs/portfolio
git switch -c tajriba
git add sayt/haqimda/index.html
git commit -m "Haqimda: yangi matnni sinab ko'r"
git add sayt/index.html
git commit -m "Bosh sahifa: havoladagi imlo xatosini tuzat"
git log --oneline main..tajriba
git switch main
git cherry-pick -x 0d59aa8
git log --oneline
git log -1 --format=%B

Biz qisqa portfolio nusxasida Loyihlar → Loyihalar xatosi bilan sinadik:

text
0d59aa8 (HEAD -> tajriba) Bosh sahifa: havoladagi imlo xatosini tuzat
38d7ce7 Haqimda: yangi matnni sinab ko'r

Cherry-pick va tekshiruvdan keyin:

text
[main bdae34f] Bosh sahifa: havoladagi imlo xatosini tuzat
 Date: Tue Oct 6 12:10:00 2026 +0500
 1 file changed, 1 insertion(+), 1 deletion(-)
bdae34f (HEAD -> main) Bosh sahifa: havoladagi imlo xatosini tuzat
f073d7f Bosh sahifa: loyihalar havolasini qo'sh
63190c1 Portfolio: 06-qism oxiridagi holat
Bosh sahifa: havoladagi imlo xatosini tuzat

(cherry picked from commit 0d59aa84226f57f3b016d94166f62aed6bcbfd10)

Sizning SHA'laringiz va tarixingiz boshqacha — oldingi darslarning commitlari ham bor. "Haqimda" tajribasi tajriba da qoldi. U tayyor bo'lganda branchni merge qilasiz — tuzatish ikki marta ko'rinadi, lekin -x izohi sababini aytib turadi.

9. Real ishda

  • Hotfix backport. Katta loyihalarda saytning bir nechta versiyasi bir vaqtda yashaydi: main dagi yangi versiya va mijozlarda ishlayotgan eski reliz-2.3 branchi. Xavfsizlik xatosi main da tuzatiladi, keyin cherry-pick -x bilan eski versiyalarga "orqaga ko'chiriladi" (backport). Mashhur ochiq loyihalarning tarixida (cherry picked from commit ...) qatorlarini tez-tez ko'rasiz.
  • GitHub'da. Ko'p loyihalarda maxsus bot PR'dagi tuzatishni eski versiya branchlariga avtomatik cherry-pick qiladi. Bu PR'lar bilan keyinroq tanishasiz.
  • Qutqarish. Tasodifan o'chib ketgan branchdagi bitta kerakli commitni boshqa joyga olish (Reflog va favqulodda yordam).
  • Intervyuda: "cherry-pick va merge farqi nima?", "cherry-pick qilingan commit nega yangi SHA oladi?" — bu darsning ikki markaziy savoli.

Xulosa

  • git cherry-pick <sha> bitta commitning o'zgarishini joriy branchga yangi commit qilib qo'shadi.
  • Yangi commit boshqa SHA oladi — ota commiti boshqa; muallif va uning sanasi saqlanadi.
  • -x xabarga (cherry picked from commit ...) yozadi — asl commit umumiy branchda bo'lsa ishlating.
  • A..B — A dan keyingi commitlar B gacha; -n — commit qilmasdan qutiga soladi.
  • Conflictda — --continue, --skip yoki --abort; bo'sh cherry-pick — --skip.
  • Butun branch kerak bo'lsa — cherry-pick emas, merge: aks holda tarixda dublikatlar ko'payadi.

Keyingi dars: Tag va relizlar — tarixdagi muhim nuqtalarga v1.0.0 kabi doimiy nom berishni o'rganamiz.

Manbalar

  • Git hujjati: "git-cherry-pick" — git-scm.com/docs/git-cherry-pick
  • Pro Git kitobi: "Maintaining a Project" (cherry-pick bo'limi) — git-scm.com/book
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Git cherry-pick: bitta commitni boshqa branchga ko'chirish — IlmHamroh