Mundarija (38)
- Bu darsda
- 1. Nega bu kerak?
- 2. Boshlang'ich holat
- 3. PR ochish
- 3.1 Branch va push
- 3.2 Brauzerda: Compare & pull request
- 3.3 Yaxshi sarlavha va tavsif
- 3.4 Closes #1 — issue'ni bog'lash
- 3.5 Draft PR — "hali tayyor emas"
- 4. PR sahifasi
- 4.1 Uch tab
- 4.2 PR'ni yangilash — shunchaki push
- 4.3 main oldinga ketsa — Update branch
- 5. Merge: uch usul
- 5.1 Tugma va ro'yxat
- 5.2 Create a merge commit
- 5.3 Squash and merge
- 5.4 Rebase and merge
- 5.5 Uchala usul yonma-yon
- 6. Merge'dan keyin: tozalash
- 6.1 Branch'ni o'chirish
- 6.2 Squash'dan keyin: not fully merged
- 6.3 Qisqa retsept
- 7. Revert: merge qilingan PR'ni bekor qilish
- 8. Ko'p uchraydigan xatolar
- 8.1 base va compare adashgan
- 8.2 PR'da o'zgarish yo'q
- 8.3 Merge'dan keyin eski main
- 8.4 PR ochiq branch'ga boshqa ish
- 8.5 Closes #1 ishlamadi
- 9. Mashqlar
- 1-mashq (oson): Qaysi usul?
- 2-mashq (o'rta): Bo'sh joylarni to'ldiring
- 3-mashq (qiyin): Tarixni o'qing
- 4-mashq: Portfolio qadami — birinchi PR
- 10. Real ishda
- Xulosa
- Manbalar
Pull Request: yaratish, muhokama va merge
Qisqacha: Pull Request (PR) — "mening branch'imdagi ishni
mainga qo'shishni taklif qilaman" degan so'rov. Uni GitHub'da ochasiz: branch'ni push qilasiz, Compare & pull request tugmasini bosasiz, sarlavha va tavsif yozasiz. PR ochiq turganda yangi commitlarni push qilsangiz, PR o'zi yangilanadi. Tayyor bo'lgach uch usuldan biri bilan birlashtiriladi: merge commit, squash yoki rebase. Keyin branch o'chiriladi, lokalmainesagit pullbilan yangilanadi.
Bu darsda
- Branch'ni GitHub'ga yuborib, undan Pull Request ochasiz.
- Yaxshi PR tavsifini yozasiz va
Closes #1bilan issue'ni bog'laysiz. - Draft PR nima ekanini va PR qanday yangilanishini ko'rasiz.
- Uch merge usulini haqiqiy repoda sinab, tarixdagi farqini
git log --graphda ko'rasiz. - Merge'dan keyingi tozalashni — branch o'chirish va
git pullni — odat qilasiz. - Birlashtirilgan PR'ni Revert bilan bekor qilasiz.
Oldin bilishingiz kerak: GitHub asoslari: repo, README, LICENSE, sozlamalar, Remote: clone, fetch, pull, push, Merge: fast-forward va uch tomonlama birlashtirish.
1. Nega bu kerak?
Oldingi darsda portfolio'ni GitHub'da professional ko'rinishga keltirdik: README, LICENSE, tavsif. «Bahor» ham README oldi va unga hamkor qo'shildi. Endi jamoa bo'lib ishlash vaqti keldi.
Hozircha ish tartibimiz shunday: branch ochamiz, commit qilamiz, main ga lokal git merge qilamiz va git push. Yolg'iz ishlaganda bu yetarli. Lekin «Bahor»da endi ikki kishi ishlaydi: Aziz va hamkasbi Malika (GitHub asoslari darsida Aziz uni repoga hamkor — collaborator — qilib qo'shgan edi). Aziz o'z ishini main ga to'g'ridan-to'g'ri yuborsa, Malika uni faqat sayt buzilganda ko'radi.
Jamoalar boshqacha ishlaydi. Branch nima darsining oxirida aytganimizdek, kompaniyalarda main ga to'g'ridan-to'g'ri commit odatda taqiqlanadi. Har ish branch'da qilinadi va main ga faqat Pull Request orqali kiradi.
Pull Request (PR) — bir branch'dagi o'zgarishlarni boshqasiga qo'shish taklifi. U GitHub'dagi alohida sahifa: unda o'zgarishlar, muhokama va "Birlashtirish" tugmasi bor. Nomi "tortib olish so'rovi" degani. Siz repo egasidan "mening o'zgarishlarimni o'zingizga tortib oling" deb so'raysiz.
Hayotiy o'xshatish: shartnoma loyihasi. Yurist matnni yozadi, lekin darhol imzolamaydi. Avval hamkasblarga yuboradi. Ular chetiga fikr yozadi, yurist tuzatadi va oxirida rahbar imzolaydi. PR — xuddi shu jarayon, faqat kod uchun.
flowchart LR
A["Branch<br/>commitlar"] --> B["git push"]
B --> C["PR ochish"]
C --> D["Muhokama<br/>va tuzatish"]
D --> C
D --> E["Merge"]
E --> F["Branchni<br/>o'chirish"]
F --> G["git pull"]Nimaga qarang: "Muhokama" va "PR ochish" orasida aylana bor. PR bir marta ochiladi, lekin tuzatishlar bilan bir necha marta yangilanadi. Merge esa faqat oxirida, bir marta bo'ladi.
Maslahat: GitLab'da xuddi shu narsa Merge Request (MR) deb ataladi. Nomi boshqa, ma'nosi bir xil.
2. Boshlang'ich holat
Darsdagi hamma buyruqlarni GitHub'dagi haqiqiy sinov reposida ishga tushirdik. Chiqishlarda repo nomini login/bahor ga almashtirdik — login o'rnida sizning GitHub nomingiz bo'ladi. PR raqamlari (#2, #3) va GitHub o'zi yaratgan commitlarning SHA'lari sizda boshqacha chiqadi.
«Bahor» Remote darsidan beri GitHub'da, lokal main esa origin/main bilan bir xil. Sinov reposidagi tarix sizdagidan qisqa: Birinchi repo darsidagi commitlar u yerda qisqaroq nomlar bilan yozilgan (Bahor: sayt tuzilmasi, Menyu: osh narxi). Sizda o'sha darsdagi nomlar bo'ladi:
cd ~/kurs/bahor
git log --oneline1dd951d (HEAD -> main, origin/main) README: loyiha tavsifini qo'sh
8c126be Sozlama: .gitignore va .gitattributes qo'sh
736a858 Bron: telefon raqamini qo'sh
58e8cd9 Bosh sahifa: aloqa havolasi
7bb2607 Menyu: osh narxi
4ff23b8 Bahor: sayt tuzilmasiJasur aka GitHub'da vazifa yozib qo'ydi: "Sharhlar sahifasi kerak". GitHub bunday vazifalarni issue deb ataydi va har biriga raqam beradi — bu #1. Issue'larni Issues, Projects va shablonlar darsida to'liq o'rganamiz. Hozir bitta narsa kerak: issue'ning raqami bor va PR uni yopa oladi.
3. PR ochish
3.1 Branch va push
Ish odatdagidek boshlanadi — branch bilan. Nomi Branch nima darsidagi kelishuv bo'yicha:
git switch -c feature/sharhlar
mkdir sharhlar
echo '<h1>Sharhlar</h1>' > sharhlar/index.html
echo "<p>«Osh zo'r!» — Malika</p>" >> sharhlar/index.html
git add sharhlar
git commit -m "Sharhlar: sahifa va birinchi sharhni qo'sh"
echo '<a href="sharhlar/">Sharhlar</a>' >> index.html
git add index.html
git commit -m "Bosh sahifa: sharhlar havolasini qo'sh"Switched to a new branch 'feature/sharhlar'
[feature/sharhlar 79d1982] Sharhlar: sahifa va birinchi sharhni qo'sh
1 file changed, 2 insertions(+)
create mode 100644 sharhlar/index.html
[feature/sharhlar 8a221f8] Bosh sahifa: sharhlar havolasini qo'sh
1 file changed, 1 insertion(+)PR GitHub'da ochiladi. Demak branch avval GitHub'da bo'lishi kerak. -u — Remote darsidan: branch'ni origin dagi nusxasi bilan bog'laydi.
git push -u origin feature/sharhlarremote:
remote: Create a pull request for 'feature/sharhlar' on GitHub by visiting:
remote: https://github.com/login/bahor/pull/new/feature/sharhlar
remote:
To https://github.com/login/bahor.git
* [new branch] feature/sharhlar -> feature/sharhlar
branch 'feature/sharhlar' set up to track 'origin/feature/sharhlar'.remote: bilan boshlangan qatorlarni Git emas, GitHub yozgan. Tarjimasi: "feature/sharhlar uchun pull request yaratish uchun shu manzilga kiring: ...". GitHub yangi branch'ni ko'rdi va darhol PR ochishni taklif qilyapti. Havolani Ctrl bosib turib bossangiz, PR sahifasi brauzerda ochiladi.
3.2 Brauzerda: Compare & pull request
Havolani bosmasangiz ham bo'ladi. docs.github.com dagi tartib bo'yicha:
- Repo sahifasini oching. Fayllar ro'yxati ustida sariq banner chiqadi — unda Compare & pull request tugmasi.
- Tugmani bosing. PR yaratish sahifasi ochiladi.
- Tepada ikki ro'yxat bor: base — qaysi branch'ga qo'shiladi (
main), compare — qaysi branch'dan (feature/sharhlar). - Sarlavha va tavsif yozing.
- Create pull request tugmasini bosing.
Yo'nalishga e'tibor bering: o'q compare'dan base'ga qaraydi. base: main ← compare: feature/sharhlar — "sharhlar branch'ini main ga qo'sh". Ikkalasini adashtirsangiz, PR teskari ishlaydi.
Tekshirib ko'ring: Nega
git pushdan oldin GitHub'da PR ochib bo'lmaydi?
Javob
PR — GitHub'dagi ikki branch orasidagi taklif. Branch hali faqat sizning kompyuteringizda bo'lsa, GitHub uni bilmaydi va solishtira olmaydi. Avval git push, keyin PR.
3.3 Yaxshi sarlavha va tavsif
Sarlavha — commit xabari kabi: qisqa, aniq, nima o'zgarganini aytadi. Biznikida: Sharhlar sahifasini qo'sh.
Tavsif esa reviewer — kodni tekshiradigan odam — uchun. U uch savolga javob bersin:
## Nima
Sharhlar sahifasi va bosh sahifada unga havola.
## Nega
Jasur aka mehmonlar fikrini saytda ko'rsatishni so'radi.
## Qanday tekshirish
1. `index.html` ni brauzerda oching.
2. "Sharhlar" havolasini bosing — sahifa ochilishi kerak.
Closes #1Tavsif — Markdown, GitHub asoslari darsidagi README kabi. "Nima" — o'zgarish mazmuni. "Nega" — sababi: kod buni aytmaydi. "Qanday tekshirish" — reviewer nimani bosib ko'rishi kerak. Yaxshi PR tavsifini Yaxshi PR tayyorlash darsida chuqurroq o'rganasiz.
3.4 Closes #1 — issue'ni bog'lash
Oxirgi qator — maxsus. GitHub hujjatiga (docs.github.com) ko'ra, tavsifda shu so'zlardan biri va issue raqami bo'lsa, PR merge bo'lganda issue avtomatik yopiladi:
| So'zlar | Misol |
|---|---|
close, closes, closed |
Closes #1 |
fix, fixes, fixed |
Fixes #12 |
resolve, resolves, resolved |
Resolves #7 |
Bitta muhim shart bor: bu so'zlar faqat PR reponing standart branch'iga (bizda main) yo'naltirilgan bo'lsa ishlaydi. PR boshqa branch'ga qaragan bo'lsa, issue ochiq qoladi.
Bir nechta issue'ni yopish uchun har biriga alohida so'z yozing: Closes #1, closes #4. Boshqa repodagi issue uchun — Fixes login/boshqa-repo#5 shakli.
3.5 Draft PR — "hali tayyor emas"
Ba'zan PR'ni ishni tugatmasdan ochgan ma'qul: hamkasblar yo'nalishni erta ko'rib, fikr bildiradi. Buning uchun draft (qoralama) PR bor. Create pull request tugmasi yonidagi ro'yxatdan Create draft pull request ni tanlaysiz.
GitHub hujjatiga ko'ra, draft PR'ni:
- merge qilib bo'lmaydi — tugma o'chiq turadi;
- kod egalariga review so'rovi avtomatik yuborilmaydi.
Biz PR'ni draft qilib ochdik. GitHub sahifasidagi ma'lumotni terminalda ham ko'rish mumkin — buni gh dasturi qiladi (GitHub CLI darsida o'rganamiz, hozir faqat natijaga qarang):
title: Sharhlar sahifasini qo'sh
state: DRAFT
author: login (Aziz Karimov)
...
number: 2
url: https://github.com/login/bahor/pull/2
additions: 3
deletions: 0state: DRAFT — qoralama. number: 2 — PR raqami. Issue va PR'lar bitta raqamlar qatoridan foydalanadi. #1 issue edi, shuning uchun PR #2 bo'ldi. additions: 3 — uch qator qo'shilgan.
4. PR sahifasi
4.1 Uch tab
PR sahifasining tepasida uchta asosiy tab bor:
| Tab | Nima bor |
|---|---|
| Conversation | Tavsif, izohlar, voqealar tarixi, pastda merge tugmasi |
| Commits | PR'dagi commitlar ro'yxati |
| Files changed | Diff — qizil va yashil qatorlar |
Files changed — git diff darsida terminalda o'qigan diff'ning o'zi, faqat rangli va qulay. U yerda qatorga izoh ham qoldirish mumkin — buni keyingi darsda qilamiz.
Esingizdami, .gitattributes darsida package-lock.json linguist-generated qatorini yozgan edik? Mana uning foydasi. GitHub hujjatiga (docs.github.com) ko'ra, bunday fayllar Files changed da standart holatda yig'ilgan turadi. Minglab qatorli lock fayl reviewer'ning ko'zini to'smaydi.
4.2 PR'ni yangilash — shunchaki push
Malika draft'ni ko'rib, "ikkinchi sharhni ham qo'shing" dedi. Yangi PR ochish shart emas. Shu branch'da commit qilib, push qilasiz:
echo "<p>«Choy doim issiq» — Jasur</p>" >> sharhlar/index.html
git add sharhlar
git commit -m "Sharhlar: ikkinchi sharhni qo'sh"
git push[feature/sharhlar 105fbe7] Sharhlar: ikkinchi sharhni qo'sh
1 file changed, 1 insertion(+)
To https://github.com/login/bahor.git
8a221f8..105fbe7 feature/sharhlar -> feature/sharhlar-u birinchi push'da sozlangan, shuning uchun endi oddiy git push yetarli. PR'ning Commits tabida endi uchta commit:
Sharhlar: sahifa va birinchi sharhni qo'sh
Bosh sahifa: sharhlar havolasini qo'sh
Sharhlar: ikkinchi sharhni qo'shPR — branch'ga qarab turgan "oyna". Branch o'zgarsa, oynadagi manzara ham o'zgaradi. Shuning uchun PR ochiq turganda o'sha branch'ga boshqa ish qo'shmang — u ham PR'ga tushadi.
Ish tugadi. Draft'ni oddiy PR'ga aylantirish uchun Conversation tabining pastidagi Ready for review tugmasini bosamiz. Teskarisi ham bor: o'ng ustundagi Reviewers bo'limi ostida Convert to draft havolasi.
Tekshirib ko'ring: Aziz PR'ni ochdi, keyin xatoni ko'rib, tuzatdi va commit qildi. Lekin
git pushni unutdi. Malika PR'da tuzatishni ko'radimi?
Javob
Yo'q. Commit faqat Aziz kompyuteridagi branch'da. PR GitHub'dagi feature/sharhlar ga qaraydi, u esa hali eski holatda. Tuzatish git push dan keyin PR'da paydo bo'ladi.
4.3 main oldinga ketsa — Update branch
PR ochiq turganda boshqalarning PR'lari main ga qo'shilib turadi. Sizning branch'ingiz ortda qoladi. GitHub hujjatiga (docs.github.com) ko'ra, bunday paytda PR sahifasida Update branch tugmasi chiqadi. U main dagi yangiliklarni branch'ingizga qo'shadi. Yonidagi ro'yxatda ikki variant: Update with merge commit va Update with rebase. Conflict bo'lsa, tugma ishlamaydi — avval conflictni yechish kerak (Conflictlarni yechish).
Tugma GitHub'dagi branch'ni o'zgartiradi. Lokal nusxangiz ortda qoladi, shuning uchun keyingi commitdan oldin git pull qiling.
5. Merge: uch usul
5.1 Tugma va ro'yxat
PR tayyor bo'lsa, Conversation tabining pastida Merge pull request tugmasi bor. Yonidagi strelka uchta usulni ochadi:
| Usul | Tarixda nima bo'ladi |
|---|---|
| Create a merge commit | Hamma commitlar + bitta merge commit (--no-ff) |
| Squash and merge | Hamma commitlar bitta yangi commitga birlashadi |
| Rebase and merge | Commitlar main ustiga bittalab qayta yoziladi |
Tanlagach, tasdiqlash tugmasi chiqadi: Confirm merge, Confirm squash and merge yoki Confirm rebase and merge. Uchalasini «Bahor»da birma-bir sinaymiz.
5.2 Create a merge commit
PR #2 ni shu usul bilan birlashtirdik. Merge GitHub'da bo'ldi — lokal main bundan bexabar. Uni yangilaymiz:
git switch main
git pullSwitched to branch 'main'
Your branch is up to date with 'origin/main'.
From https://github.com/login/bahor
1dd951d..e00abfd main -> origin/main
Updating 1dd951d..e00abfd
Fast-forward
index.html | 1 +
sharhlar/index.html | 3 +++
2 files changed, 4 insertions(+)
create mode 100644 sharhlar/index.htmlDiqqat qiling: switch "up to date" dedi, lekin bu yolg'on emas. Git origin/main ning oxirgi ma'lum holatiga qarab gapiradi — u GitHub'dagi merge'ni hali ko'rmagan. git pull yangilikni olib keldi. Endi tarix:
git log --oneline --graph -6* e00abfd (HEAD -> main, origin/main, origin/HEAD) Merge pull request #2 from login/feature/sharhlar
|\
| * 105fbe7 (origin/feature/sharhlar, feature/sharhlar) Sharhlar: ikkinchi sharhni qo'sh
| * 8a221f8 Bosh sahifa: sharhlar havolasini qo'sh
| * 79d1982 Sharhlar: sahifa va birinchi sharhni qo'sh
|/
* 1dd951d README: loyiha tavsifini qo'sh
* 8c126be Sozlama: .gitignore va .gitattributes qo'shMerge darsidagi --no-ff ning aynan o'zi: uch commit o'z shaklida qoldi, ustidan ikki otali merge commit qo'shildi. main oldinga ketmagan bo'lsa ham, GitHub fast-forward qilmadi. Merge commit xabarini GitHub o'zi yozdi:
git log -1 --format='%h%n%s%n%n%b'e00abfd
Merge pull request #2 from login/feature/sharhlar
Sharhlar sahifasini qo'shBirinchi qatorda PR raqami, pastda PR sarlavhasi. Bir yildan keyin ham bu commitdan PR'ni topib, butun muhokamani o'qish mumkin.
Issue nima bo'ldi? #1 ning holati endi CLOSED. Uni yopgan PR — #2. Closes #1 qatori ishladi.
5.3 Squash and merge
Endi Aziz menyuga narxlar qo'shdi — shoshilib, uchta yomon commit bilan:
git switch -c feature/menyu-narxlar
# ... uch o'zgarish, uch commit ...
git log --oneline main..HEAD11c4e7e (HEAD -> feature/menyu-narxlar) narx tuzatildi
0c69f6f somsa
dc40fda wipInteraktiv rebase bilan tozalasa bo'lardi. Lekin GitHub'da tayyor yo'l bor. PR #3 ni Squash and merge bilan birlashtirdik:
git switch main
git pull --prune
git log --oneline --graph -4Switched to branch 'main'
Your branch is up to date with 'origin/main'.
From https://github.com/login/bahor
- [deleted] (none) -> origin/feature/menyu-narxlar
e00abfd..d4d6fc8 main -> origin/main
Updating e00abfd..d4d6fc8
Fast-forward
menyu/index.html | 2 ++
1 file changed, 2 insertions(+)
* d4d6fc8 (HEAD -> main, origin/main, origin/HEAD) Menyu: choy va somsa narxlarini qo'sh (#3)
* e00abfd Merge pull request #2 from login/feature/sharhlar
|\
| * 105fbe7 Sharhlar: ikkinchi sharhni qo'sh
| * 8a221f8 Bosh sahifa: sharhlar havolasini qo'sh--prune va [deleted] qatorini birozdan keyin, branch o'chirish bo'limida tushuntiramiz. Hozir tarixga qarang: main da wip, somsa yo'q. Bitta yangi commit — sarlavhasi PR nomi, oxirida (#3). Ichiga qaraymiz:
git show --stat --format='%h %s%n%n%b' HEADd4d6fc8 Menyu: choy va somsa narxlarini qo'sh (#3)
* wip
* somsa
* narx tuzatildi
---------
Co-authored-by: Aziz Karimov <aziz@example.com>
menyu/index.html | 2 ++
1 file changed, 2 insertions(+)Eski commit xabarlari tavsifga ro'yxat bo'lib tushdi. GitHub hujjatiga (docs.github.com) ko'ra, standart xabar shunday tuziladi. PR'da bitta commit bo'lsa — o'sha commitning xabari, ikki va undan ko'p bo'lsa — PR sarlavhasi va commitlar ro'yxati. Repo sozlamalarida (Settings → General → Pull Requests) buni o'zgartirish mumkin.
Co-authored-by: — "hammuallif". Sinovda commitlar aziz@example.com manzili bilan qilindi, PR esa boshqa GitHub akkauntidan ochildi. Squash commit muallifi PR egasi bo'ldi, commitlarning asl muallifini esa GitHub hammuallif qilib qo'shdi. Commitlar va akkaunt bir odamniki bo'lsa, bu qator chiqmasligi mumkin.
5.4 Rebase and merge
Uchinchi PR #4 — ikki toza commit: telefon raqamidagi xato va Telegram manzili. Lokal branch'da ularning SHA'si:
4751963 (HEAD -> fix/telefon) Aloqa: Telegram manzilini qo'sh
ed3d120 Bron: telefon raqamini tuzatRebase and merge bilan birlashtirdik va git pull --prune qildik:
git log --oneline --graph -5* 63af265 (HEAD -> main, origin/main, origin/HEAD) Aloqa: Telegram manzilini qo'sh
* 0186333 Bron: telefon raqamini tuzat
* d4d6fc8 Menyu: choy va somsa narxlarini qo'sh (#3)
* e00abfd Merge pull request #2 from login/feature/sharhlar
|\
| * 105fbe7 Sharhlar: ikkinchi sharhni qo'shMerge commit yo'q, ikkala commit alohida, tarix chiziqli. Lekin SHA'larga qarang: ed3d120 → 0186333, 4751963 → 63af265. Xabarlar o'sha, commitlar esa yangi. Rebase darsidagi kabi, commitlar main uchiga qayta qo'llandi.
Muallif va commit qilgan odamni ham ko'ramiz:
git log --format='%h %s | muallif: %an | commit qilgan: %cn' -263af265 Aloqa: Telegram manzilini qo'sh | muallif: Aziz Karimov | commit qilgan: login
0186333 Bron: telefon raqamini tuzat | muallif: Aziz Karimov | commit qilgan: login(Ikkinchi ism o'rnida sinovdagi GitHub akkauntining ismi chiqdi — uni login ga almashtirdik.)
GitHub hujjati shu farqni alohida ta'kidlaydi: GitHub'ning Rebase and merge i commit qilgan odam ma'lumotini har doim yangilaydi va yangi SHA yaratadi. Oddiy git rebase esa, kerak bo'lmasa, commitni qayta yaratmaydi.
5.5 Uchala usul yonma-yon
gitGraph
commit id: "1dd951d README"
branch feature
commit id: "79d1982"
commit id: "8a221f8"
commit id: "105fbe7"
checkout main
merge feature id: "e00abfd #2 merge"
commit id: "d4d6fc8 #3 squash"
commit id: "0186333 #4 rebase"
commit id: "63af265 #4 rebase"Nimaga qarang: #2 dan keyin main da uch xil iz qoldi. Merge commit — branch shakli va ikki ota saqlangan. Squash — uch commit o'rnida bitta. Rebase — commitlar alohida, lekin yangi SHA bilan, merge commitsiz.
Qaysi biri yaxshi? Yagona javob yo'q:
- Merge commit — eng to'liq tarix. Har PR chegarasi ko'rinadi. Katta jamoalarda ko'p.
- Squash —
mainda "bitta PR = bitta commit". Commitlari tartibsiz PR'lar uchun qulay. Ko'p jamoalarda standart. - Rebase — commitlari allaqachon toza va har biri alohida ma'noli bo'lsa.
Repo egasi keraksiz usullarni sozlamalarda o'chirib qo'yishi mumkin. Shunda ro'yxatda faqat ruxsat etilganlari qoladi.
Tekshirib ko'ring: PR'da
wip,typo,wip 2commitlari bor. Uni Rebase and merge qilsangiz,maintarixida nima ko'rinadi?
Javob
Uchala yomon commit — wip, typo, wip 2 — main ga alohida-alohida tushadi, faqat yangi SHA bilan. Rebase merge commitlarni birlashtirmaydi. Bunday PR uchun Squash and merge to'g'ri. Yoki PR'dan oldin interaktiv rebase bilan tozalash kerak edi.
6. Merge'dan keyin: tozalash
6.1 Branch'ni o'chirish
Merge'dan keyin PR sahifasida Delete branch tugmasi chiqadi. U GitHub'dagi feature/sharhlar ni o'chiradi. Branch o'z ishini qildi — u endi main ning bir qismi. Har safar bosmaslik uchun repo sozlamasi bor: Settings → General → Pull Requests bo'limida Automatically delete head branches belgisi.
O'chirish faqat GitHub'da bo'ldi. Lokal kompyuterda ikkita qoldiq qoladi:
git branch -a feature/sharhlar
* main
remotes/origin/HEAD -> origin/main
remotes/origin/feature/sharhlar
remotes/origin/mainremotes/origin/feature/sharhlar — GitHub'da yo'q branch'ning eskirgan nusxasi. Oddiy git fetch uni o'chirmaydi. --prune ("kesib tashlash") — GitHub'da yo'q branch'larning nusxalarini o'chiradi:
git fetch --pruneFrom https://github.com/login/bahor
- [deleted] (none) -> origin/feature/sharhlarEndi lokal branch. Merge commit usulida uning commitlari main da bor, shuning uchun -d muammosiz o'chiradi:
git branch -d feature/sharhlarDeleted branch feature/sharhlar (was 105fbe7).6.2 Squash'dan keyin: not fully merged
Squash qilingan branch bilan esa boshqacha:
git branch -d feature/menyu-narxlarerror: the branch 'feature/menyu-narxlar' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature/menyu-narxlar'
hint: Disable this message with "git config set advice.forceDeleteBranch false"Tarjimasi: "xato: feature/menyu-narxlar branch'i to'liq birlashtirilmagan. O'chirishga ishonchingiz komil bo'lsa — git branch -D ...". Lekin biz uni birlashtirdik-ku! Nega Git bunday deydi?
Git commitlarni SHA bo'yicha tekshiradi. dc40fda, 0c69f6f, 11c4e7e — main da yo'q. U yerda ular o'rnida mazmuni bir xil, lekin boshqa SHA'li d4d6fc8 turibdi. Git buni bilmaydi va ehtiyot bo'lib to'xtaydi. Rebase merge'dan keyin ham xuddi shu xabar chiqadi — SHA'lar yana yangi.
PR merge bo'lganiga ishonchingiz komil bo'lsa — katta -D:
git branch -D feature/menyu-narxlarDeleted branch feature/menyu-narxlar (was 11c4e7e).Diqqat:
-Dni faqat PR sahifasida Merged yozuvini ko'rgandan keyin ishlating. PR yopilgan, lekin merge qilinmagan bo'lsa,-Dhaqiqatan ham ishni o'chiradi. Shunda yordamga Reflog keladi.
6.3 Qisqa retsept
Har PR merge'dan keyin:
git switch main
git pull --prune
git branch -d feature/nomi # "not fully merged" bo'lsa: -Dgit pull --prune ikki ishni birga qiladi: yangi main ni oladi va o'chirilgan branch'lar nusxasini tozalaydi. Uni har safar yozmaslik uchun git config --global fetch.prune true sozlamasi bor.
7. Revert: merge qilingan PR'ni bekor qilish
Jasur aka qo'ng'iroq qildi: "Choy va somsa narxlari hali tasdiqlanmagan, olib tashlang!" PR #3 allaqachon main da.
Reset va revert darsida aytgan edik: birlashtirilgan PR sahifasining pastida Revert tugmasi bor. GitHub hujjatiga (docs.github.com) ko'ra, u asl o'zgarishni bekor qiladigan yangi PR ochadi. Uni ham boshqa PR'lar kabi merge qilish kerak. Tugma ko'rinmasa, repoga yozish huquqingiz yo'q.
Biz Revert ni bosdik. GitHub #5 raqamli PR ochdi:
Revert "Menyu: choy va somsa narxlarini qo'sh"
revert-3-feature/menyu-narxlar
Reverts login/bahor#3Sarlavha, GitHub o'zi yaratgan branch nomi va tavsif. PR #5 ni merge qilib, git pull dan keyin:
* 939993c (HEAD -> main, origin/main, origin/HEAD) Merge pull request #5 from login/revert-3-feature/menyu-narxlar
|\
| * 0071479 Revert "Menyu: choy va somsa narxlarini qo'sh (#3)"
|/
* 63af265 Aloqa: Telegram manzilini qo'sh
* 0186333 Bron: telefon raqamini tuzat0071479 ning ichi:
0071479 Revert "Menyu: choy va somsa narxlarini qo'sh (#3)"
This reverts commit d4d6fc804fde72b1f23937bfc94d49c2ee18ee4c.
menyu/index.html | 2 --
1 file changed, 2 deletions(-)git revert ning aynan o'zi — xabar ham o'sha shaklda. Squash commit tarixda qoldi, ustidan teskari commit qo'shildi. Hech narsa qayta yozilmadi, shuning uchun hech kim zarar ko'rmaydi.
GitHub hujjati yana bir narsani eslatadi: revert conflict bersa yoki asl PR GitHub'da emas, boshqa yo'l bilan birlashtirilgan bo'lsa, commitlarni alohida — terminalda git revert bilan — bekor qilish kerak bo'ladi.
8. Ko'p uchraydigan xatolar
8.1 base va compare adashgan
PR'da base: feature/sharhlar ← compare: main. Bu "main ni sharhlar branch'iga qo'sh" degani — teskari. Belgi: PR'da sizga notanish ko'p commit chiqadi. Tuzatish: PR'ni yopib, to'g'ri yo'nalishda qayta oching. Yoki docs.github.com dagi yo'l bilan base branch'ni almashtiring: sarlavha yonidagi Edit title, base ro'yxatidan to'g'ri branch, keyin Change base.
8.2 PR'da o'zgarish yo'q
PR yaratish sahifasida diff bo'sh, Create pull request tugmasi esa chiqmaydi. Ya'ni solishtiradigan narsa yo'q: compare branch'da base'da yo'q commit topilmadi. Sabablari: commit qildingiz, lekin push qilmadingiz. Yoki commitni xato main ga qildingiz. Tuzatish: git log --oneline origin/main..feature/nomi — bo'sh chiqsa, branch'da GitHub biladigan yangi commit yo'q.
8.3 Merge'dan keyin eski main
GitHub'da merge bo'ldi, Aziz esa lokal main dan yangi branch ochdi va git pull ni unutdi. Yangi branch eski main dan o'sdi — sharhlar sahifasisiz. Tuzatish: har yangi ishdan oldin git switch main va git pull. Agar kech payqasangiz — git rebase main (Rebase).
8.4 PR ochiq branch'ga boshqa ish
Aziz feature/sharhlar PR'i ochiq turganda, xuddi shu branch'da menyuni ham tuzatdi va push qildi. Menyu tuzatishi sharhlar PR'iga tushdi. Tuzatish: har ish — o'z branch'i, har branch — o'z PR'i. Menyu commitini Cherry-pick bilan yangi branch'ga ko'chirib, eski branch'dan interaktiv rebase bilan olib tashlang.
8.5 Closes #1 ishlamadi
PR main ga emas, masalan dev branch'iga yo'naltirilgan edi. Kalit so'zlar faqat standart branch'ga qaragan PR'da ishlaydi. Yoki raqam xato: Closes #11 o'rniga Closes #1. Bunda boshqa issue yopiladi — PR yaratishdan oldin raqamni tekshiring. Xato bo'lsa, issue'ni qo'lda qayta oching.
9. Mashqlar
1-mashq (oson): Qaysi usul?
Har holat uchun merge usulini tanlang:
- PR'da 7 ta commit:
wip,fix,fix 2,ok, ... Hammasi bitta ish. - PR'da uch toza commit: "Menyu: sahifani qo'sh", "Menyu: narxlarni qo'sh", "Bosh sahifa: menyu havolasini qo'sh". Jamoa chiziqli tarixni yoqtiradi.
- Jamoa har PR'ning qachon va qaysi commitlar bilan kirganini tarixda aniq ko'rishni xohlaydi.
Yechim
- Squash and merge — yetti tartibsiz commit
mainda bitta toza commitga aylanadi. - Rebase and merge — uch commit alohida qoladi va merge commit bo'lmaydi.
- Create a merge commit — PR chegarasi merge commit bilan belgilanadi, ichidagi commitlar o'z shaklida qoladi.
2-mashq (o'rta): Bo'sh joylarni to'ldiring
PR merge bo'lgandan keyingi tozalash. Branch squash bilan birlashtirilgan:
git switch
git pull
git branch feature/aloqa-xaritaIshora: «Merge'dan keyin: tozalash» bo'limi. Squash'dan keyin -d nima deydi?
Yechim
git switch main
git pull --prune
git branch -D feature/aloqa-xarita--prune GitHub'da o'chirilgan branch nusxasini tozalaydi. Squash yangi SHA'li commit yaratgani uchun -d "not fully merged" deydi. PR Merged bo'lganiga ishonch hosil qilib, -D ishlatamiz.
3-mashq (qiyin): Tarixni o'qing
git pull dan keyin main tarixi shunday:
* 7c1e2a9 Bron: forma tekshiruvini qo'sh (#14)
* a3b9f10 Merge pull request #12 from login/fix/narx
|\
| * 5d6e7f1 Menyu: osh narxini tuzat
|/
* 9e8d7c6 Aloqa: xaritani qo'sh
* 2b3c4d5 Aloqa: ish vaqtini qo'sh(SHA'lar misol uchun.) 9e8d7c6 va 2b3c4d5 ham bitta PR #11 dan kelgan.
- Har PR qaysi usul bilan birlashtirilgan?
#14da nechta commit bo'lganini shu tarixdan bilib bo'ladimi?#11ning commitlari lokal branch'dagi SHA'lar bilan bir xilmi?
Yechim
#12— Create a merge commit:Merge pull requestxabari va ikki ota.#14— Squash and merge: sarlavha oxirida(#14), bitta commit.#11— Rebase and merge: ikki commit chiziqda, merge commit ham,(#11)ham yo'q.- Bir qatordan bilib bo'lmaydi. Lekin
git show 7c1e2a9commit tavsifida eski commitlar ro'yxatini ko'rsatadi — agar PR'da ikki va undan ko'p commit bo'lgan bo'lsa. - Yo'q. Rebase and merge har doim yangi SHA yaratadi. Shuning uchun keyin lokal branch'ni
-dbilan o'chirib bo'lmaydi.
4-mashq: Portfolio qadami — birinchi PR
Portfolio Remote darsidan beri GitHub'dagi login.github.io bilan bog'langan. Bugundan boshlab unga o'zgarish faqat PR orqali kiradi — hatto yolg'iz ishlasangiz ham. Bu odat keyin jamoada tayyor bo'lib keladi.
mainni yangilang vafeature/haqimda-kursbranch'ini oching.- "Haqimda" sahifasiga bitta qator qo'shing: hozir qaysi kursni o'qiyotganingiz. Commit xabari kelishuv bo'yicha:
Haqimda: kurs haqida qator qo'sh. - Branch'ni push qiling va terminaldagi
remote:havolasi orqali PR oching. - Tavsifda "Nima", "Nega", "Qanday tekshirish" bo'limlarini yozing.
- Files changed tabida diff'ni o'zingiz o'qib chiqing.
- Squash and merge bilan birlashtiring va Delete branch ni bosing.
- Lokal tozalashni bajaring. Bir-ikki daqiqadan keyin saytingizni oching — yangi qator ko'rinadimi?
Yechim
cd ~/kurs/portfolio
git switch main
git pull
git switch -c feature/haqimda-kurs
# sayt/haqimda/index.html ga bitta <p> qator qo'shing
git add sayt/haqimda/index.html
git commit -m "Haqimda: kurs haqida qator qo'sh"
git push -u origin feature/haqimda-kursPush natijasida remote: Create a pull request for 'feature/haqimda-kurs' ... qatori va havola chiqadi — «Bahor»dagi kabi. PR merge bo'lgach:
git switch main
git pull --prune
git branch -D feature/haqimda-kurs
git log --oneline -2Squash bo'lgani uchun -d o'rniga -D kerak bo'ladi («Squash'dan keyin» bo'limi). git log tepasida PR sarlavhasi va raqami bilan bitta commit turadi, masalan ... Haqimda: kurs haqida qator qo'sh (#1). Portfolio'da issue yo'q bo'lsa, birinchi PR #1 bo'ladi.
Saytdagi o'zgarish uchun hech narsa qilmadingiz: Remote darsida Pages manbasini GitHub Actions'ga o'tkazgan edingiz. main o'zgarishi bilan sayt o'zi yangilanadi. Bu qanday ishlashini GitHub Actions va GitHub Pages darslarida ochamiz.
10. Real ishda
- Har o'zgarish — PR orqali. Kompaniyalarda
mainhimoyalangan: unga to'g'ridan-to'g'ri push qilib bo'lmaydi, faqat PR va review'dan keyin. Buni sozlashni Branch himoyasi darsida ko'rasiz. - Kichik PR tez merge bo'ladi. 50 qatorli PR'ni hamkasb bir soatda ko'radi, 2 000 qatorlisini — bir haftada. Katta ishni bir nechta kichik PR'ga bo'ling.
- PR — hujjat. Bir yildan keyin "bu qator nega shunday?" degan savolga git blame commitni, commit esa PR raqamini ko'rsatadi. PR'da butun muhokama saqlangan.
- Avtomatik tekshiruvlar. PR ochilishi bilan testlar o'zi ishga tushadi va natijasi PR sahifasida ko'rinadi (GitHub Actions). Ko'p loyihalarda bot tuzatishni eski versiya branch'lariga ham avtomatik cherry-pick qiladi.
- Intervyuda so'raladi: "Squash va rebase merge farqi?", "PR tavsifiga nima yozasiz?", "Merge'dan keyin nega
git branch -dxato beradi?" Bu dars uchalasiga javob.
Xulosa
- Pull Request — branch'ni
mainga qo'shish taklifi: o'zgarishlar, muhokama va merge tugmasi bitta sahifada. - Tartib: branch → commit →
git push -u→ Compare & pull request → tavsif → Create pull request. - Tavsif: nima, nega, qanday tekshirish.
Closes #1— merge'da issue'ni yopadi (faqat standart branch'ga PR'da). - Draft PR'ni merge qilib bo'lmaydi; tayyor bo'lsa — Ready for review. PR'ni yangilash — shunchaki
git push. - Merge usullari: merge commit (
--no-ff), squash (bitta yangi commit), rebase (commitlar yangi SHA bilan). - Keyin: Delete branch, lokalda
git pull --prunevagit branch -d(squash/rebase'dan keyin-D). - Revert tugmasi o'zgarishni bekor qiladigan yangi PR ochadi.
Keyingi dars: GitHub'da code review amaliyoti — PR'ni boshqa tomondan, reviewer ko'zi bilan ko'ramiz: qatorga izoh, suggestion, Approve va Request changes.
Manbalar
- GitHub Docs: "Creating a pull request", "Changing the stage of a pull request", "Linking a pull request to an issue" — docs.github.com
- GitHub Docs: "About merge methods on GitHub", "Merging a pull request", "Configuring commit squashing for pull requests" — docs.github.com
- GitHub Docs: "Keeping your pull request in sync with the base branch", "Managing the automatic deletion of branches", "Reverting a pull request" — docs.github.com
- Git hujjati: "git-fetch" (
--prune), "git-branch" (-d,-D) — git-scm.com/docs
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!