Mundarija (39)
- Bu darsda
- 1. Nega bu kerak?
- 2. Ruleset va branch himoyasi
- 2.1 Ta'rif
- 2.2 Ikki xil vosita
- 2.3 Kimda ishlaydi va qancha turadi
- 3. Ruleset yaratish
- 3.1 Sahifaga yo'l
- 3.2 Nom, holat va bypass
- 3.3 Qaysi branchlar: target
- 4. Qoidalar bittalab
- 4.1 Ikki standart qoida
- 4.2 Require a pull request before merging
- 4.3 Require linear history
- 4.4 Qolgan qoidalar
- 4.5 Saqlash
- 5. Push rad etildi: GH013
- 5.1 Qoidani buzib ko'ramiz
- 5.2 Commit qayerda qoldi?
- 5.3 Commitni branch'ga ko'chirish
- 5.4 PR va merge
- 6. Force-push va o'chirish
- 6.1 Force-push
- 6.2 main ni o'chirish
- 7. Hujumchi nigohi
- 8. Ko'p uchraydigan xatolar
- 8.1 Ruleset yaratdim, lekin push o'tib ketyapti
- 8.2 "Merge commits are not allowed on this repository."
- 8.3 O'zimni bloklab qo'ydim
- 8.4 Brauzerda fayl tahrirlay olmayapman
- 8.5 GH013 ni ko'rib, --force yozish
- 9. Mashqlar
- 1-mashq (oson): Qoidani toping
- 2-mashq (o'rta): Xabarni o'qing
- 3-mashq (qiyin): «Bahor» jamoasi uchun ruleset
- 4-mashq: Portfolio qadami — main himoyasi
- 10. Real ishda
- Xulosa
- Manbalar
GitHub branch himoyasi va rulesets: main'ni tasodifiy push'dan saqlash
Qisqacha: Ruleset — GitHub'dagi branch uchun qoidalar to'plami: "main'ga faqat Pull Request orqali", "force-push yo'q", "o'chirish yo'q". Qoida buzilsa, GitHub push'ni rad etadi va
GH013: Repository rule violations foundxabarini qaytaradi. Ruleset Settings → Rules → Rulesets sahifasida yaratiladi va public repolarda bepul. Eski usul — klassik branch himoyasi (branch protection rule) — ham ishlaydi, ikkalasi birga qo'llanadi.
Bu darsda
- Ruleset nima ekanini va u klassik branch himoyasidan nimasi bilan farq qilishini tushuntira olasiz.
- GitHub'da
mainuchun ruleset yaratasiz: maqsadli branch, holat (Active/Disabled), bypass ro'yxati. - Asosiy qoidalarni tanlay olasiz: o'chirish va force-push taqiqi, majburiy PR, review, chiziqli tarix, status check.
GH013xatosini o'qiysiz va rad etilgan commitni yo'qotmasdan PR yo'liga o'tkazasiz.- Portfolio'ingizning
mainbranchini himoyalaysiz.
Oldin bilishingiz kerak: Pull Request: yaratish, muhokama, merge, GitHub'da code review amaliyoti, Ajralgan tarix: pull --rebase va force-with-lease.
1. Nega bu kerak?
Pull Request darsida kelishib oldik: o'zgarish avval branch'da yoziladi, PR'da ko'riladi, keyin main ga qo'shiladi. Lekin bu — faqat kelishuv. Git hech kimni git push origin main yozishdan to'xtatmaydi.
Tasavvur qiling. «Bahor» saytida endi uch kishi ishlaydi: siz, Malika va stajyor Sardor. Kech soat 23:00 da Sardor menyu/ dagi narxni tuzatib, to'g'ridan-to'g'ri main ga yubordi. Bitta qavs yopilmay qolgan ekan. Sayt avtomatik yangilandi va menyu sahifasi buzildi. Ertalab mehmonlar narxlarni ko'ra olmadi.
Ikkinchi hafta yana bir voqea. Malika o'z tarixini rebase qildi va shoshib git push --force yozdi. Uning nusxasi eski edi — sizning kechagi uchta commitingiz main dan yo'qoldi. Ajralgan tarix darsida bunga qarshi --force-with-lease ni o'rgangan edik. Lekin u ham faqat yozgan odamning e'tiboriga bog'liq: charchagan odam baribir --force yozib yuboradi.
Bunday xatolarni "ehtiyot bo'linglar" degan gap to'xtatmaydi. Qoidani server tekshirishi kerak. GitHub'da buning vositasi bor — ruleset.
Hayotiy o'xshatish: bank kassasi. Kassir pulni qo'lda istalgancha bera olardi. Lekin bank tizimi har to'lovni tekshiradi: imzo yo'q — to'lov o'tmaydi. Kassir qanchalik tajribali bo'lmasin, qoida hamma uchun bir xil. Ruleset ham shunday: kim yozganidan qat'i nazar, qoidani buzgan push qabul qilinmaydi.
2. Ruleset va branch himoyasi
2.1 Ta'rif
Ruleset (qoidalar to'plami) — repodagi branch yoki taglarga qo'yiladigan nomli qoidalar ro'yxati. Masalan, "main himoyasi" nomli ruleset: main ni o'chirish mumkin emas, unga force-push mumkin emas, o'zgarish faqat PR orqali keladi.
GitHub qoidani push vaqtida tekshiradi. Siz git push yozasiz, commitlar serverga yetib boradi, GitHub ularni qoidalar bilan solishtiradi. Mos kelmasa — butun push rad etiladi va sizga sababi aytiladi. Repoda hech narsa o'zgarmaydi.
Bu himoya faqat terminal uchun emas. GitHub hujjatiga ko'ra, himoyalangan branch'da fayllarni brauzer orqali tahrirlab yoki yuklab bo'lmaydi. Birinchi deploy darsida portfolio fayllarini aynan shunday yuklagan edingiz. Endi bu yo'l ham yopiladi — o'zgarish faqat branch va PR orqali.
2.2 Ikki xil vosita
GitHub'da branchni himoyalashning ikki yo'li bor:
| Klassik branch himoyasi | Ruleset | |
|---|---|---|
| Inglizcha nomi | Branch protection rule | Ruleset |
| Bitta branch'ga nechta | Faqat bittasi ishlaydi | Bir nechtasi birga |
| Vaqtincha o'chirish | Faqat o'chirib tashlab | Holatini Disabled qilib |
| Kim ko'ra oladi | Admin | O'qish huquqi bor hamma |
Ruleset — yangiroq va moslashuvchan vosita. Bir nechta ruleset bitta branch'ga tushsa, qoidalar qo'shiladi. Bir qoida turlicha yozilgan bo'lsa, eng qattig'i ishlaydi. Masalan, bir rulesetda 1 ta, boshqasida 2 ta review talab qilinsa — 2 ta kerak bo'ladi. Klassik himoya ham shu hisobga qo'shiladi.
Ikkinchi muhim farq — adminlar. Klassik himoya, standart holatda, repo adminlariga tegmaydi: ular qoidani chetlab o'ta oladi. Buni yopish uchun alohida "Do not allow bypassing the above settings" katagi bor. Rulesetda esa aksincha: chetlab o'tish huquqi faqat bypass ro'yxatiga yozilganlarda. Ro'yxat bo'sh bo'lsa, repo egasi ham qoidaga bo'ysunadi.
Kursda ruleset ishlatamiz. Eski loyihalarda klassik himoyani ko'p uchratasiz — u Settings → Branches sahifasida, Add classic branch protection rule tugmasi bilan yaratiladi. Qoidalarning nomlari va ma'nosi deyarli bir xil.
2.3 Kimda ishlaydi va qancha turadi
GitHub hujjatiga ko'ra (2026-yil oktabr holati): ruleset va klassik himoya public repolarda bepul GitHub Free tarifida ishlaydi. Private repoda ular uchun pullik tarif kerak (Pro, Team yoki Enterprise). Portfolio repongiz login.github.io — public, demak bepul.
Bitta repoda 75 tagacha ruleset bo'lishi mumkin. Odatda 1–3 tasi yetadi.
Tekshirib ko'ring: Repoda ikkita ruleset
mainga qaraydi. Birinchisi force-push'ni taqiqlaydi, ikkinchisi PR talab qiladi.mainga qaysi qoidalar ishlaydi?
Javob
Ikkalasi ham. Rulesetlar bir-birini almashtirmaydi — qoidalari yig'iladi. main ga endi force-push ham mumkin emas, PR'siz push ham. Klassik himoyada esa bitta branch'ga faqat bitta qoida ishlardi.
3. Ruleset yaratish
3.1 Sahifaga yo'l
Qadamlar GitHub hujjatidan (docs.github.com, "Creating rulesets for a repository"):
- Repo sahifasida Settings tabini bosing. Ko'rinmasa —
...menyusidan Settings ni tanlang. - Chap paneldagi "Code and automation" bo'limida Rules → Rulesets ni bosing.
- New ruleset → New branch ruleset ni tanlang.
Menyuda New tag ruleset ham bor — u taglarni himoyalaydi: masalan, v* taglarini hech kim o'chira olmasin. Import a ruleset esa tayyor JSON faylidan ruleset yaratadi — bir xil qoidani ko'p repoga qo'yish uchun qulay.
3.2 Nom, holat va bypass
Ochilgan formada birinchi uchta maydon:
- Ruleset name — nom. Biz
main himoyasideb yozdik. Nom faqat odamlar uchun — qisqa va tushunarli bo'lsin. - Enforcement status — holat. Active — qoida darhol ishlaydi. Disabled — ruleset saqlanadi, lekin ishlamaydi. Yangi forma standart holatda Disabled bo'ladi — Active ni o'zingiz tanlang. (Uchinchi holat — Evaluate: qoida faqat kuzatadi va hisobot yozadi. U faqat Enterprise tariflarida bor.)
- Bypass list — qoidani chetlab o'ta oladiganlar. Add bypass tugmasi bilan rol (masalan Repository admin), jamoa yoki ilova qo'shiladi.
Maslahat: Bypass ro'yxatini bo'sh qoldiring. "Men egasiman, menga mumkin" — aynan kechasi 23:00 dagi xatoning boshlanishi. Qoida hamma uchun bir xil bo'lsa, unga ishonsa bo'ladi.
3.3 Qaysi branchlar: target
"Target branches" bo'limida Add a target tugmasi bor. Uchta yo'l:
- Include default branch — standart branch (bizda
main). Keyin branch nomi o'zgarsa ham, qoida yangisiga o'tadi. - Include all branches — hammasi.
- Include by pattern — shablon bo'yicha. Masalan
release/**/*—release/bilan boshlanadigan hamma branch.
Shablondagi yulduzchalar .gitignore dagiga o'xshaydi: * — / gacha bo'lgan istalgan nom, ** — istalgan chuqurlikdagi papkalar. GitHub hujjati bu sintaksisni fnmatch deb ataydi — nomini bilish shart emas. Exclude by pattern bilan istisno ham qo'shish mumkin.
Portfolio uchun bitta target yetadi: Include default branch.
4. Qoidalar bittalab
"Branch protections" bo'limida qoidalar ro'yxati turadi. Har birining yonida katak. Ba'zilarini tanlaganingizda qo'shimcha sozlamalar ochiladi.
4.1 Ikki standart qoida
Yangi rulesetda ikkitasi oldindan belgilangan:
- Restrict deletions — branchni o'chirish taqiqlanadi (bypass ro'yxatidagilardan tashqari).
- Block force pushes — force-push taqiqlanadi. Ajralgan tarix darsidagi
--forceham,--force-with-leaseham.
Ikkalasini ham qoldiring. Ular main tarixini o'chib ketishdan saqlaydi.
4.2 Require a pull request before merging
Eng muhim qoida: branch'ga o'zgarish faqat PR orqali keladi. GitHub hujjatida aytilishicha, PR tasdiqlangan bo'lishi shart emas — ochilgan bo'lishi kifoya. To'g'ridan-to'g'ri push rad etiladi.
Uni tanlaganingizda qo'shimcha sozlamalar ochiladi:
| Sozlama | Nima qiladi |
|---|---|
| Required approvals | Merge'dan oldin nechta tasdiq (approve) kerak |
| Dismiss stale pull request approvals when new commits are pushed | Yangi commit kelsa, eski tasdiq bekor bo'ladi |
| Require review from Code Owners | Fayl "egasi" tasdiqlashi shart |
| Require approval of the most recent reviewable push | Oxirgi push'ni boshqa odam tasdiqlashi kerak |
| Require conversation resolution before merging | Hamma izoh "hal qilindi" bo'lishi kerak |
| Allowed merge methods | Qaysi merge usullariga ruxsat: merge, squash, rebase |
Code review darsidagi tasdiqlash aynan shu yerda majburiy bo'ladi. Jamoada odatda 1 ta tasdiq so'raladi.
Bir muhim nuqta: o'z PR'ingizni o'zingiz tasdiqlay olmaysiz. Yolg'iz ishlasangiz va "1 ta tasdiq" ni yoqsangiz, PR'ni hech kim merge qila olmaydi. Shuning uchun portfolio'da tasdiqlar sonini 0 qoldiramiz: PR majburiy, tasdiq — yo'q. Bu xatoning haqiqiy matnini keyingi darsda terminalda ko'rasiz.
"Code Owners" — fayllarga mas'ul odamlar ro'yxati, ya'ni Code review darsida yozgan CODEOWNERS faylingiz. Bu katak yoqilsa, ular faqat avtomatik chaqirilmaydi — ularning tasdig'isiz merge bo'lmaydi.
4.3 Require linear history
Chiziqli tarix (linear history) — main da merge commit bo'lmaydi. PR'ni faqat squash yoki rebase usuli bilan qo'shish mumkin. Bu usullarni Pull Request darsida ko'rgan edik.
gitGraph
commit id: "3fbf72b Pages"
branch feature/aloqa-telegram
checkout feature/aloqa-telegram
commit id: "ecffd19 Telegram"
checkout main
commit id: "a2a3d58 Telegram (#4)"Nimaga qarang: squash usulida branch'dagi commit main ga yangi commit sifatida tushadi (a2a3d58), PR raqami (#4) bilan. main chizig'ida ayri yo'q — tarix bitta to'g'ri chiziq. Branch esa merge'dan keyin o'chiriladi.
Nega bu foydali? Chiziqli tarixda git log --oneline toza o'qiladi. Xato commitni revert qilish ham oson: har PR — bitta commit.
4.4 Qolgan qoidalar
Jadvalda yangi so'z bor: CI — har push'da kodni GitHub serverida avtomatik tekshiradigan tizim. Uni ikki darsdan keyin quramiz, hozir nomini bilish yetarli.
| Qoida | Qisqacha |
|---|---|
| Require status checks to pass | Avtomatik tekshiruv (CI) o'tmasa, merge yo'q |
| Require signed commits | Faqat imzolangan commitlar |
| Require deployments to succeed before merging | Avval sinov serveriga deploy o'tishi kerak |
| Restrict creations / updates | Branchni yaratish yoki yangilash faqat bypass bilan |
| Require merge queue | PR'lar navbat bilan, birga sinalib qo'shiladi |
Require status checks to pass — eng kuchli himoyalardan biri. U PR'dagi avtomatik tekshiruv (masalan, npm run check) muvaffaqiyatli bo'lishini talab qiladi. Bizda hali bunday tekshiruv yo'q. Uni GitHub Actions: birinchi CI workflow darsida yaratamiz va shu rulesetga qo'shamiz.
Shu qoidaning ichida Require branches to be up to date before merging katagi bor. U belgilansa ("strict" — qattiq rejim), PR branchi main ning eng oxirgi holatini o'z ichiga olishi shart. Belgilanmasa ("loose" — yumshoq rejim), eski asosdagi PR ham qo'shilaveradi.
Require merge queue — katta jamoalar uchun. GitHub hujjatiga ko'ra, u faqat tashkilotga (organization) tegishli repolarda ishlaydi. Shaxsiy repo uchun — yo'q.
4.5 Saqlash
Formaning pastidagi Create tugmasi. Holat Active bo'lsa, qoida shu zahoti ishlaydi. Keyin o'zgartirish uchun rulesetning nomini bosasiz va Save changes qilasiz.
Biz sinov reposida aynan shunday ruleset yaratdik. Target — default branch. Qoidalar to'rtta: o'chirish taqiqi, force-push taqiqi, chiziqli tarix va majburiy PR (0 ta tasdiq, izohlar hal qilinishi shart, faqat squash va rebase). GitHub uni ichida JSON shaklida saqlaydi — Import a ruleset aynan shu formatni o'qiydi:
{
"name": "main himoyasi",
"target": "branch",
"enforcement": "active",
"conditions": {
"ref_name": { "include": ["~DEFAULT_BRANCH"], "exclude": [] }
},
"rules": [
{ "type": "deletion" },
{ "type": "non_fast_forward" },
{ "type": "required_linear_history" },
{
"type": "pull_request",
"parameters": {
"required_approving_review_count": 0,
"dismiss_stale_reviews_on_push": false,
"require_code_owner_review": false,
"require_last_push_approval": false,
"required_review_thread_resolution": true,
"allowed_merge_methods": ["squash", "rebase"]
}
}
]
}Bu faylni yozish shart emas — formadagi kataklar aynan shuni hosil qiladi. Lekin uni o'qiy olish foydali. ~DEFAULT_BRANCH — "standart branch" degan maxsus belgi. non_fast_forward — force-push taqiqining ichki nomi. Keyingi darsda bu JSON'ni terminaldan ham yaratamiz.
Tekshirib ko'ring: Siz portfolio ustida yolg'iz ishlaysiz. "Required approvals" ni 1 qilsangiz nima bo'ladi?
Javob
Hech bir PR merge bo'lmaydi. Tasdiqni muallifdan boshqa odam berishi kerak, siz esa yolg'izsiz. Yechim — tasdiqlar sonini 0 qoldirish: PR baribir majburiy, tarix tartibli, lekin o'zingizni bloklab qo'ymaysiz.
5. Push rad etildi: GH013
5.1 Qoidani buzib ko'ramiz
Ruleset yaratildi. Endi odatdagidek ishlaymiz — aloqa sahifasiga Telegram havolasini qo'shib, to'g'ridan-to'g'ri main ga yuboramiz. Chiqishlarda repo nomini login/login.github.io ga almashtirdik: biz vaqtinchalik sinov reposida ishladik, sizda o'z loginingiz turadi.
Sinov reposidagi portfolio tarixi juda qisqa: boshlang'ich commit va Pages workflow'i. Ikkinchisi u yerda qisqaroq nom bilan yozilgan — Deploy: Pages workflow'ini qo'sh. Sizda esa Remote darsidagi Deploy: sayt/ ni Pages'ga yuklaydigan workflow qo'sh va 07-qismdagi boshqa commitlaringiz turadi.
git commit -m "Aloqa: Telegram havolasini qo'sh"
git push[main ecffd19] Aloqa: Telegram havolasini qo'sh
1 file changed, 4 insertions(+)
remote: error: GH013: Repository rule violations found for refs/heads/main.
remote: Review all repository rules at https://github.com/login/login.github.io/rules?ref=refs%2Fheads%2Fmain
remote:
remote: - Changes must be made through a pull request.
remote:
To https://github.com/login/login.github.io.git
! [remote rejected] main -> main (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/login/login.github.io.git'Commit lokal yaratildi. Push esa rad etildi. Qatorma-qator:
remote:bilan boshlanadigan qatorlar — GitHub serverining javobi. Remote darsidagi kabi.GH013: Repository rule violations found for refs/heads/main— tarjimasi: "mainbranchi uchun repo qoidalari buzilgan".GH013— GitHub'ning shu xato turi uchun kodi. Internetda qidirsangiz, aynan shu kod bilan qidiring.Review all repository rules at ...— "barcha qoidalarni shu manzilda ko'ring". Repo manziliga/rulesqo'shilgan sahifa — o'qish huquqi bor har kim ko'ra oladi.Changes must be made through a pull request.— tarjimasi: "O'zgarishlar Pull Request orqali kiritilishi kerak". Buzilgan qoida — Require a pull request before merging.! [remote rejected] ... (push declined due to repository rule violations)— "server rad etdi: qoidalar buzilgani uchun push qabul qilinmadi".
E'tibor bering: bu [rejected] emas, [remote rejected]. Oddiy [rejected] ni Remote darsida ko'rgansiz — u "sizning nusxangiz eski" degani. [remote rejected] esa "server qabul qilmadi": commitlar yetib bordi, lekin qoida o'tkazmadi.
5.2 Commit qayerda qoldi?
git status -sb## main...origin/main [ahead 1]ahead 1 — lokal main GitHub'dagidan bitta commit oldinda. Commit yo'qolmadi, u faqat kompyuteringizda. Endi uni to'g'ri yo'lga o'tkazamiz.
5.3 Commitni branch'ga ko'chirish
Reja: commit turgan joyda yangi branch ochamiz, main ni esa GitHub'dagi holatga qaytaramiz.
git switch -c feature/aloqa-telegram
git branch -f main origin/main
git log --oneline --allSwitched to a new branch 'feature/aloqa-telegram'
branch 'main' set up to track 'origin/main'.
ecffd19 (HEAD -> feature/aloqa-telegram) Aloqa: Telegram havolasini qo'sh
3fbf72b (origin/main, origin/HEAD, main) Deploy: Pages workflow'ini qo'sh
59df546 Portfolio: 06-qism oxiridagi holatgit switch -c— yangi branch yaratib, unga o'tish (Branch nima). Uecffd19ni ko'rsatadi — commit endi shu branch'da.git branch -f main origin/main—mainko'rsatkichini majburanorigin/mainga surish.-f— "force". Bizmainda turmaganimiz uchun bu xavfsiz: ishchi papkaga tegmaydi.
Endi main va origin/main bir joyda (3fbf72b). Commit esa feature/aloqa-telegram da. Branchni yuboramiz:
git push -u origin feature/aloqa-telegramremote:
remote: Create a pull request for 'feature/aloqa-telegram' on GitHub by visiting:
remote: https://github.com/login/login.github.io/pull/new/feature/aloqa-telegram
remote:
To https://github.com/login/login.github.io.git
* [new branch] feature/aloqa-telegram -> feature/aloqa-telegram
branch 'feature/aloqa-telegram' set up to track 'origin/feature/aloqa-telegram'.Bu safar o'tdi. Ruleset faqat main ga qaraydi — boshqa branchlarga erkin push qilish mumkin. GitHub hatto PR ochish havolasini ham berdi.
5.4 PR va merge
Pull Request darsidagidek havolani ochib, PR yarating. PR sahifasining pastidagi merge oynasida (merge box) endi qoidalar ham ko'rinadi.
Merge tugmasi yonidagi strelkani bosing. Chiziqli tarix qoidasi tufayli Create a merge commit usuli ishlamaydi. Biz uni terminaldan sinab ko'rdik, GitHub javobi:
Merge commits are not allowed on this repository.Tarjimasi: "Bu repoda merge commitlarga ruxsat yo'q". Squash and merge ni tanlang. Merge'dan keyin GitHub branchni o'chirishni taklif qiladi — o'chiring. Keyin kompyuterda:
git switch main
git pull
git log --onelineSwitched to branch 'main'
Your branch is up to date with 'origin/main'.
From https://github.com/login/login.github.io
3fbf72b..a2a3d58 main -> origin/main
Updating 3fbf72b..a2a3d58
Fast-forward
sayt/aloqa/index.html | 4 ++++
1 file changed, 4 insertions(+)
a2a3d58 (HEAD -> main, origin/main, origin/HEAD) Aloqa: Telegram havolasini qo'sh (#4)
3fbf72b Deploy: Pages workflow'ini qo'sh
59df546 Portfolio: 06-qism oxiridagi holatup to date ga aldanmang: Git origin/main ni oxirgi fetch dagi holatda eslaydi. git pull esa avval yangisini olib keladi — 3fbf72b..a2a3d58. main da yangi commit — a2a3d58, oxirida PR raqami (#4). Bu squash merge belgisi. Bizning sinov reposida bu to'rtinchi PR edi; sizda raqam ham, SHA ham boshqacha bo'ladi — squash commit merge qilingan vaqtdan hisoblanadi.
Lokal feature/aloqa-telegram branchi endi keraksiz:
git branch -d feature/aloqa-telegramwarning: deleting branch 'feature/aloqa-telegram' that has been merged to
'refs/remotes/origin/feature/aloqa-telegram', but not yet merged to HEAD
Deleted branch feature/aloqa-telegram (was ecffd19).Branch o'chdi, lekin ogohlantirish bilan. Tarjimasi: "branch origin/feature/aloqa-telegram ga qo'shilgan, lekin HEAD'ga hali qo'shilmagan". Sababi — squash: main ga ecffd19 ning o'zi emas, uning nusxasi (a2a3d58) tushdi. Git buni bilmaydi.
Nega baribir o'chirdi? Git lokal xotiradagi origin/feature/aloqa-telegram ni ko'rdi va "commit u yerda saqlangan" deb ruxsat berdi. GitHub'da branch allaqachon o'chirilgan bo'lsa ham, bu xotira git fetch --prune gacha eski holatda turadi (Remote darsi). U ham bo'lmaganda, -d rad etardi va -D kerak bo'lardi (Branch nima darsidagi farq).
Butun yo'l bitta rasmda:
flowchart TD
A["git push origin main"] --> B{"Ruleset<br/>tekshiradi"}
B -- "qoida buzilgan" --> C["GH013<br/>remote rejected"]
C --> D["git switch -c feature/..."]
D --> E["git push -u origin<br/>feature/..."]
E --> F["Pull Request"]
F --> G{"Qoidalar<br/>bajarilganmi?"}
G -- "ha" --> H["Squash and merge<br/>main yangilandi"]
G -- "yo'q" --> FNimaga qarang: main ga yagona eshik — PR. To'g'ridan-to'g'ri yo'l (git push origin main) qizil chiziqqa olib keladi va siz baribir branch–PR yo'liga qaytasiz.
6. Force-push va o'chirish
6.1 Force-push
Endi ataylab ikkinchi qoidani buzamiz. Lokal main ni bitta commit orqaga qaytarib, ustiga boshqa commit qildik. Endi u GitHub'dagi main dan ayrilgan. Oddiy push:
git pushTo https://github.com/login/login.github.io.git
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/login/login.github.io.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.Bu — Git'ning o'z himoyasi, Ajralgan tarix darsidan tanish. Rulesetsiz repoda ham shunday bo'ladi. Ilgari bu yerda --force "yechim" edi. Endi:
git push --forceremote: error: GH013: Repository rule violations found for refs/heads/main.
remote: Review all repository rules at https://github.com/login/login.github.io/rules?ref=refs%2Fheads%2Fmain
remote:
remote: - Cannot force-push to this branch
remote:
remote: - Changes must be made through a pull request.
remote:
To https://github.com/login/login.github.io.git
! [remote rejected] main -> main (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/login/login.github.io.git'Endi ikkita qoida buzilgan. Cannot force-push to this branch — tarjimasi: "Bu branch'ga force-push qilib bo'lmaydi". GitHub buzilgan hamma qoidani ro'yxat qilib beradi — bittasini tuzatib, ikkinchisiga urilmaysiz.
Lokal main ni qanday tuzatish kerak? Ayrilgan commit kerak bo'lsa — uni branch'ga oling (yuqoridagi switch -c usuli). Keraksiz bo'lsa — git reset --hard origin/main (reset va revert).
6.2 main ni o'chirish
git push origin --delete mainTo https://github.com/login/login.github.io.git
! [remote rejected] main (refusing to delete the current branch: refs/heads/main)
error: failed to push some refs to 'https://github.com/login/login.github.io.git'Tarjimasi: "joriy branchni o'chirishdan bosh tortildi". Qiziq: bu yerda GH013 yo'q. main — reponing standart branchi, GitHub uni rulesetsiz ham o'chirtirmaydi. Restrict deletions qoidasi standart bo'lmagan branchlar uchun kerak bo'ladi — masalan, release/* shabloni bilan himoyalangan branchlar uchun.
Tekshirib ko'ring:
[rejected]va[remote rejected]— ikkalasi ham push o'tmadi degani. Farqi nimada?
Javob
[rejected] — Git'ning o'zi push'ni boshlamasdan to'xtatdi: lokal tarix GitHub'dagidan orqada yoki ayrilgan. [remote rejected] — commitlar serverga yetib bordi, lekin server (GitHub ruleseti) ularni qabul qilmadi. Birinchisida git pull kerak, ikkinchisida — PR yo'li.
7. Hujumchi nigohi
Ruleset faqat adashgan odamdan emas, yomon niyatli odamdan ham saqlaydi. Tasavvur qiling: noutbukingizdagi GitHub tokeni o'g'irlandi (SSH kalit va autentifikatsiya darsidagi «Hujumchi nigohi»).
- Rulesetsiz: hujumchi
mainga zararli kod yuboradi. Sayt avtomatik yangilanadi — mehmonlarga uning sahifasi chiqadi. Yokigit push --forcebilan butun tarixni o'chiradi. - Ruleset bilan:
mainga to'g'ridan-to'g'ri push ham, force-push hamGH013bilan qaytadi. Hujumchi PR ochishga majbur — PR esa hammaga ko'rinadi va izini qoldiradi.
Shuning uchun bypass ro'yxati bo'sh bo'lsin: unda turgan har bir akkaunt — hujumchi uchun ochiq eshik. Lekin to'liq kafolat yo'q: admin huquqli token rulesetni o'chirib qo'yishi ham mumkin. Ikkinchi qatlam — tokenlarga faqat kerakli ruxsatni berish (fine-grained token) va 2FA.
8. Ko'p uchraydigan xatolar
8.1 Ruleset yaratdim, lekin push o'tib ketyapti
Eng ko'p sabab — holat Disabled qolgan. Yangi forma standart holatda Disabled bo'ladi. Settings → Rules → Rulesets ro'yxatida rulesetni oching va Enforcement status ni Active qiling.
Ikkinchi sabab — target yo'q. "Target branches" bo'sh bo'lsa, ruleset hech qaysi branch'ga qo'llanmaydi. Uchinchisi — o'zingiz bypass ro'yxatidasiz.
8.2 "Merge commits are not allowed on this repository."
PR'ni Create a merge commit bilan qo'shmoqchi bo'ldingiz, chiziqli tarix esa yoqilgan. Tugma yonidagi strelkadan Squash and merge yoki Rebase and merge ni tanlang.
8.3 O'zimni bloklab qo'ydim
Yolg'iz loyihada "Required approvals: 1" yoqilgan — PR merge bo'lmaydi. Rulesetni oching, tasdiqlar sonini 0 qiling va Save changes. Bypass ro'yxatiga o'zingizni qo'shish — yomon yechim: qoida "hammaga, mendan tashqari" bo'lib qoladi.
8.4 Brauzerda fayl tahrirlay olmayapman
Himoyalangan branch'da GitHub saytida faylni tahrirlash va yuklash yopiladi (GitHub hujjatida shunday). Bu xato emas — himoya ishlayapti. Tahrirni branch'da qiling va PR oching.
8.5 GH013 ni ko'rib, --force yozish
Qo'rqib, git push --force bilan "zo'rlab" yuborishga urinish — foydasiz. Force-push ham qoida bilan yopilgan, xabarlar soni faqat ko'payadi. GH013 — "yo'l boshqa" degani: branch → PR.
9. Mashqlar
Javoblaringizni mashqlar reposida 07/33-branch-himoyasi/javoblar.md fayliga yozib, 07/33: branch himoyasi javoblarini qo'sh xabari bilan commit qiling.
1-mashq (oson): Qoidani toping
Har vaziyatga ruleset qoidasini (inglizcha nomi bilan) toping:
- Stajyor
mainga to'g'ridan-to'g'ri push qildi. - Malika
git push --forcebilan hamkasbining commitlarini o'chirdi. maintarixida "Merge pull request #12 ..." kabi merge commitlar ko'p,git logni o'qish qiyin.- Hech kim ko'rmagan kod
mainga tushdi.
Yechim
- Require a pull request before merging — to'g'ridan-to'g'ri push rad etiladi.
- Block force pushes — force-push yopiladi.
- Require linear history — faqat squash yoki rebase merge.
- Require a pull request before merging + Required approvals: 1 — kamida bitta odam tasdiqlashi kerak. Faqat PR yetmaydi: GitHub hujjatiga ko'ra, PR ochilgan bo'lishi kifoya, tasdiq shart emas.
2-mashq (o'rta): Xabarni o'qing
Malika git push yozdi va shuni oldi:
remote: error: GH013: Repository rule violations found for refs/heads/main.
remote: - Cannot force-push to this branch
remote: - Changes must be made through a pull request.
! [remote rejected] main -> main (push declined due to repository rule violations)Bo'sh joylarni to'ldiring. Push'ni Git emas, [:server] rad etdi — buni [remote rejected] dagi "remote" so'zi bildiradi. Ikkita qoida buzilgan: force-push taqiqi va majburiy [:PR]. Malika yozgan buyruqda ehtimol -- flagi bor edi.
Ishora: «Force-push va o'chirish» bo'limidagi ikki qoidali xabarni solishtiring.
Yechim
server, PR, force. Oddiy git push force-push qilmaydi. Shuning uchun Cannot force-push qatori Malika --force (yoki --force-with-lease) yozganini ko'rsatadi. To'g'ri yo'l — commitlarini yangi branch'ga olib, PR ochish.
3-mashq (qiyin): «Bahor» jamoasi uchun ruleset
«Bahor» reposida uch kishi ishlaydi: siz (admin), Malika va stajyor Sardor. Talablar:
mainga faqat PR orqali, kamida bitta tasdiq bilan.- Yangi commit kelsa, eski tasdiq kuchini yo'qotsin.
- Tarix chiziqli bo'lsin.
release/bilan boshlanadigan branchlarni hech kim o'chira olmasin va force-push qila olmasin, lekin ularga PR talab qilinmasin.
Nechta ruleset kerak? Har birida qaysi target va qaysi qoidalar? Bypass ro'yxati qanday bo'ladi?
Ishora: bitta rulesetning hamma qoidasi uning hamma targetiga qo'llanadi («Ruleset va branch himoyasi» bo'limi).
Yechim
Ikkita ruleset kerak, chunki main va release/* uchun qoidalar har xil.
1. main himoyasi — target: Include default branch.
- Restrict deletions, Block force pushes.
- Require a pull request before merging: Required approvals — 1, Dismiss stale pull request approvals when new commits are pushed — yoqilgan.
- Require linear history.
2. reliz himoyasi — target: Include by pattern release/**/*.
- Restrict deletions, Block force pushes. Boshqa hech narsa.
Bypass ro'yxati ikkalasida ham bo'sh — siz admin bo'lsangiz ham. Agar release/* ni bitta rulesetga qo'shsangiz, ularga ham PR va tasdiq talabi tushardi — shart buziladi.
Uch kishilik jamoada siz yozgan PR'ni Malika yoki Sardor tasdiqlaydi — "1 ta tasdiq" bloklamaydi.
4-mashq: Portfolio qadami — main himoyasi
Portfolio'ingiz Remote darsidan beri GitHub'da va har push'da Pages'ga chiqadi. Endi uning main branchini himoyalaymiz.
login.github.ioreposida Settings → Rules → Rulesets → New ruleset → New branch ruleset.- Nom:
main himoyasi. Holat: Active. Bypass ro'yxati — bo'sh. - Target: Include default branch.
- Qoidalar: Restrict deletions va Block force pushes (standart), Require linear history, Require a pull request before merging.
- PR qoidasining sozlamalari: Required approvals — 0, Require conversation resolution before merging — yoqilgan, Allowed merge methods — Squash va Rebase.
- Create.
- Sinov: aloqa sahifasiga bitta qator qo'shing (masalan Telegram havolasi), commit qiling va
git push—GH013chiqishi kerak. - Commitni
feature/...branch'ga oling,mainniorigin/mainga qaytaring, branchni yuboring, PR oching va Squash and merge qiling. git switch main,git pull,git log --oneline— oxirgi commitda(#N)bormi?
landing reposida ham xuddi shu rulesetni yarating.
Yechim
7-qadamdagi chiqish «Push rad etildi: GH013» bo'limidagidek bo'ladi. Faqat login o'rnida sizning loginingiz turadi.
8-qadam:
git switch -c feature/aloqa-telegram
git branch -f main origin/main
git push -u origin feature/aloqa-telegramPR'ni GitHub chiqargan havola orqali oching. Merge'dan keyin:
git switch main
git pull
git branch -D feature/aloqa-telegram
git log --onelineOxirgi commit ... (#N) ko'rinishida bo'lsa (raqam sizda boshqacha bo'lishi mumkin) — hammasi to'g'ri.
landing uchun 1–6 qadamlar takrorlanadi. Vaqtni tejash usuli ham bor: portfolio rulesetini ochib, ... menyusidagi tarixdan (History) JSON'ni yuklab oling (Download). Keyin landing da New ruleset → Import a ruleset orqali shu faylni tanlang.
Bundan keyin portfolio'dagi har o'zgarish branch va PR orqali boradi. Keyingi darslarda shu yo'lga terminal vositasi (gh) va avtomatik tekshiruv qo'shiladi.
10. Real ishda
- Deyarli har kompaniyada
mainhimoyalangan: PR majburiy, kamida 1–2 tasdiq, CI o'tishi shart. Ishga kirganingizda birinchi push'ingizGH013bilan qaytsa — ajablanmang, bu normal. - Ochiq kodli loyihalarda ham shunday. Ko'p repolarning qoidalarini
/rulessahifasida ko'rish mumkin — masalan, GitHub hujjatlari reposigithub.com/github/docs/rules. - Tag himoyasi — reliz taglarini (
v*) o'chirish va surishni taqiqlash. Tag va relizlar darsidagi "tag joyidan qimirlamaydi" va'dasini server darajasida kafolatlaydi. - Intervyuda: "main'ni qanday himoyalaysiz?", "Squash va merge commit farqi?", "Force-push'ni qachon ishlatish mumkin?" Javob: o'z feature branchingizda — ha (
--force-with-leasebilan),mainda — hech qachon.
Xulosa
- Kelishuvni server tekshirishi kerak: ruleset — branch yoki tag uchun nomli qoidalar to'plami.
- Yaratish: Settings → Rules → Rulesets → New branch ruleset; holat Active, target — default branch, bypass — bo'sh.
- Asosiy qoidalar: o'chirish va force-push taqiqi, majburiy PR, chiziqli tarix; jamoada — tasdiqlar soni.
- Yolg'iz loyihada tasdiqlar soni 0: o'z PR'ingizni o'zingiz tasdiqlay olmaysiz.
GH013 ... [remote rejected]— server qoidasi; yechim — commitni branch'ga olib, PR ochish.- Rulesetlar qo'shiladi va eng qattiq qoida ishlaydi; klassik branch himoyasi ham ular bilan birga ishlaydi.
Keyingi dars: GitHub CLI (gh) — PR, issue va rulesetlarni brauzerga chiqmasdan, terminaldan boshqarishni o'rganamiz.
Manbalar
- GitHub Docs: "About rulesets", "Creating rulesets for a repository", "Available rules for rulesets", "Managing rulesets for a repository" — docs.github.com
- GitHub Docs: "About protected branches", "Managing a branch protection rule" — docs.github.com
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!