Mundarija (32)
- Bu darsda
- 1. Nega bu kerak?
- 2. GitHub flow
- 2.1 Qoidalar
- 2.2 Kanon tajribasi: sinov reposidagi 10 ta PR
- 2.3 Bitta PR'ning hayoti
- 2.4 Natija: chiziqli main
- 2.5 Kimga mos
- 3. Trunk-based development
- 3.1 Qoidalar
- 3.2 Kanon tajribasi
- 3.3 Narxi
- 4. Git-flow
- 4.1 Qoidalar
- 4.2 Kanon tajribasi
- 4.3 Narxi va qachon mos
- 5. Taqqoslash
- 6. Branch nomlash
- 7. Loyiha qadami: vazifalar-api uchun GitHub flow
- 8. Ko'p uchraydigan xatolar
- 8.1 GH013 — to'g'ridan push
- 8.2 Fast-forward bo'lmadi
- 8.3 Uzoq yashovchi branch
- 8.4 "Can not approve your own pull request"
- 8.5 Hotfix bir joyga
- 9. Mashqlar
- 1-mashq (oson): bo'shliqlarni to'ldiring
- 2-mashq (o'rta): eski branch'larni topish
- 3-mashq (qiyin): ikki dasturchi, bitta trunk
- 10. Real ishda
- Xulosa
- Manbalar
Jamoa workflow'lari: GitHub flow, trunk-based va git-flow
Qisqacha: Workflow — jamoaning branch bilan ishlash kelishuvi: qayerdan branch ochiladi, u qancha yashaydi, qayerga qo'shiladi va reliz qanday chiqadi. GitHub flow —
maindoim tayyor, har ish qisqa branch va PR orqali. Trunk-based — branch'lar soatlab yashaydi, tayyor bo'lmagan ish feature flag ortidamainga tushadi. Git-flow —main+developva release/hotfix branch'lari, versiyalangan relizlar uchun. Kanon tajribasida bir xil 3 ta o'zgarish trunk-based'da 5 commit va 0 merge commit, git-flow'da 11 commit va 6 merge commit qoldirdi. Ko'p veb jamoalar uchun boshlang'ich tanlov — GitHub flow.
Bu darsda
- Uch workflow'ning qoidalarini va ular qoldiradigan tarixni solishtirasiz.
- GitHub flow'ni kurs sinov reposidagi haqiqiy PR'lar misolida ko'rasiz: ruleset rad etishlari bilan.
- Trunk-based'da
--ff-onlyva rebase bilan chiziqli tarix qurasiz. - Git-flow'da release va hotfix branch'lari qanday ishlashini va narxini tushuntirasiz.
- Branch nomlash kelishuvini yozasiz va tekshirasiz.
Oldin bilishingiz kerak: Pull Request: yaratish, muhokama, merge, Branch himoyasi va rulesets, Rebase: tarixni chiziqlash, Feature flag'lar backend'da.
1. Nega bu kerak?
Tasavvur qiling: vazifalar-api ustida endi besh kishi ishlaydi. Aziz main ga to'g'ridan push qiladi. Nodira bir haftalik branch ochgan, u main dan 40 commit orqada. Sardor develop degan branch yaratib, hammani unga merge qilishga undayapti. Reliz kuni hech kim bilmaydi: qaysi branch'dan chiqaramiz?
Muammo Git'da emas — kelishuvda. Git hamma usulga ruxsat beradi. Jamoaga esa umumiy qoidalar kerak:
- Yangi ish qayerdan boshlanadi?
- Branch qancha yashaydi?
- U qayerga va qanday qo'shiladi (merge, squash, rebase)?
- Reliz qayerdan va qachon chiqadi? Shoshilinch tuzatish (hotfix) qanday o'tadi?
Bu savollarga javoblar to'plami workflow (ish oqimi) deyiladi.
Hayotiy o'xshatish: chorraha. Svetofor bo'lmasa ham mashinalar o'tadi, lekin sekin va avariya bilan. Kichik ko'chada "o'ngdagi o'tadi" qoidasi yetadi, katta chorrahada — svetofor va burilish yo'laklari kerak. Workflow ham shunday: jamoa va reliz ritmiga mos bo'lsin. Ortiqcha murakkab qoidalar kichik jamoani sekinlashtiradi.
2. GitHub flow
2.1 Qoidalar
GitHub flow — eng sodda va eng keng tarqalgan workflow. GitHub hujjatidagi oltita qadam (docs.github.com, "GitHub flow", 2026-11-04 da o'qildi):
maindan yangi branch oching, nomi nima qilinayotganini aytsin.- Branch'da o'zgartiring, commit qiling va uni GitHub'ga yuboring.
- Pull Request oching: tavsif yozing va hamkasblardan fikr so'rang.
- Review (kod ko'rib chiqish) izohlariga yangi commitlar bilan javob bering.
- PR tasdiqlangach —
mainga merge. - Branch'ni o'chiring.
Bu qadamlar ortida bitta tamoyil turadi: main doim ishlaydigan holatda, uni istalgan payt deploy qilsa bo'ladi. Hujjatda bu so'zma-so'z yozilmagan, lekin oqim shunga qurilgan: o'zgarish main ga faqat review'dan keyin tushadi.
gitGraph
commit id: "import"
branch fix/31-nuqsonlari
commit id: "breaker"
checkout main
commit id: "#9 squash"
branch chore/reliz-4.0.1
commit id: "4.0.1"
checkout main
commit id: "#11 squash"Diagrammaga qarang. Har branch qisqa: bitta ish, bitta PR. Merge'dan keyin main da bitta commit paydo bo'ladi (squash — PR'ning hamma commitlari bittaga siqiladi). Branch'lar main ga qaytmaydi — ular o'chiriladi.
2.2 Kanon tajribasi: sinov reposidagi 10 ta PR
Kurs sinov reposida (github.com/Sarvarbek0704/ilmhamroh-git-sinov) 32-qism davomidagi har o'zgarish GitHub flow bilan o'tdi: 10 ta PR, hammasi squash bilan. Avval main himoyalandi — ruleset (Branch himoyasi va rulesets darsi). Kanon uni gh api orqali JSON fayldan yaratdi (bitta uzun qator telefon uchun bo'lindi, mazmun aynan):
{
"name": "main himoyasi",
"target": "branch",
"enforcement": "active",
"conditions": {
"ref_name": { "include": ["~DEFAULT_BRANCH"], "exclude": [] }
},
"bypass_actors": [],
"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": true,
"require_code_owner_review": false,
"require_last_push_approval": false,
"required_review_thread_resolution": true,
"allowed_merge_methods": ["squash"] } }
]
}Qoidalarni o'qiymiz:
deletion,non_fast_forward—mainni o'chirish va force push taqiqlangan.required_linear_history—mainda merge commit bo'lmaydi, tarix chiziqli.pull_request— faqat PR orqali;required_review_thread_resolution— hamma muhokamalar yopilmaguncha merge yo'q;allowed_merge_methods— faqat squash.required_approving_review_count: 0— tasdiq soni nol. Bu bitta odamli sinov reposining cheklovi: GitHub o'z PR'ingizni tasdiqlashga ruxsat bermaydi (pastda isbot). Jamoada kamida 1 tasdiq va CODEOWNERS review qo'yiladi (Git va monorepo darsida).
Ruleset ishlayaptimi? Kanon main ga to'g'ridan push qildi. Chiqishda repo manzili login/vazifalar-api ga almashtirildi:
remote: error: GH013: Repository rule violations found for refs/heads/main.
remote: Review all repository rules at https://github.com/login/vazifalar-api/rules?ref=refs%2Fheads%2Fmain
remote:
remote: - Changes must be made through a pull request.
remote:
To https://github.com/login/vazifalar-api.git
! [remote rejected] main -> main (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/login/vazifalar-api.git'"O'zgarishlar pull request orqali kiritilishi kerak." GitHub flow'ning birinchi qoidasi endi faqat kelishuv emas — server uni majburlaydi.
2.3 Bitta PR'ning hayoti
Birinchi PR — Bisect darsidagi 31-qism nuqsonlari. Kanon buyruqlari (repo nomi almashtirildi):
git switch -c fix/31-nuqsonlari
# ... commit (Bisect darsidagi tuzatish)
git push -u origin fix/31-nuqsonlari
T="fix(ai): har modelga alohida circuit breaker"
T+=" va umumiy deadline; 31-qism nuqsonlari"
gh pr create --base main --head fix/31-nuqsonlari \
--title "$T" --body-file pr.mdKeyin review keldi: kodning aniq qatorlariga to'rtta izoh (savol:, taklif:, maqtov:) — ularni Code review darsida batafsil o'qiymiz. Endi ikki haqiqiy rad etish.
O'z PR'ini tasdiqlash:
gh pr review 9 --approve -b "LGTM"failed to create review: GraphQL: Review Can not approve your own pull request (addPullRequestReview)"O'z pull request'ingizni tasdiqlay olmaysiz." Shuning uchun sinov reposida tasdiq soni 0 — aks holda bitta odam hech narsani merge qila olmasdi.
Ochiq muhokama bilan merge:
gh pr merge 9 --squashX Pull request login/vazifalar-api#9 is not mergeable: the base branch policy prohibits the merge.
To have the pull request merged after all the requirements have been met, add the `--auto` flag.
To use administrator privileges to immediately merge the pull request, add the `--admin` flag."PR merge qilinmaydi: asosiy branch siyosati taqiqlaydi." Ikki savol hali javobsiz edi. Muallif javob yozdi, taklifni alohida issue'ga chiqardi, keyin to'rtta muhokama yopildi va merge o'tdi:
{"commit":"22a1226","mergedAt":"2026-11-03T19:21:42Z","state":"MERGED"}E'tibor bering: chiqishdagi ikkinchi maslahat — --admin bilan qoidani chetlab o'tish. Bu imkoniyat bor, lekin "muhokama yopilmaguncha merge yo'q" qoidasi aynan shunday shoshilishga qarshi yozilgan.
2.4 Natija: chiziqli main
10 ta PR'dan keyin main tarixi (gh api dan, oxirgi 12 commit):
7f8f2d4 docs(sayt): README — sinov repo izohi va reja yangilandi (#20)
a9550ae docs: vazifalar-api uchun MIT LICENSE va hissa litsenziyasi (#19)
ca2a135 docs: takrorlanuvchi vazifalar — talab hujjati (#18)
f12ef28 docs: issue shablonlari, ADR va muloqot qoidalari (#17)
0ae90b7 docs: README qayta tuzildi, qo'llanmalar docs/qanday ga (2/2) (#15)
8fff1c5 docs: CONTRIBUTING, SECURITY va PR shabloni (1/2) (#14)
29d20db docs: arxitektura xaritasi va birinchi vazifa yo'riqnomasi (#13)
8ec1500 chore(repo): CODEOWNERS va CI path filtri; actions @v7 (#12)
6e0d3e9 chore(release): 4.0.1 — CHANGELOG.md; fix(mcp): server versiyasi package.json dan (#11)
22a1226 fix(ai): har modelga alohida circuit breaker va umumiy deadline; 31-qism nuqsonlari (#9)
9c395ca feat(vazifalar-api): 31-qism yakuni (v4.0.0) — kurs loyihasi sinov repoga
c70c84c LICENSE: MIT litsenziyasini qo'shHar qator — bitta PR, oxirida raqami. Merge commit yo'q, har commit Conventional Commits formatida. Bunday tarix bilan Bisect ham, CHANGELOG ham oson ishlaydi. PR ichidagi oraliq commitlar ("tuzatdim", "review izohi") main ga tushmadi — squash ularni siqdi.
Narxi ham bor. Squash'dan keyin PR ichidagi tafsilotli tarix main da yo'q — u faqat GitHub'dagi PR sahifasida qoladi. Katta PR bitta katta commitga aylanadi: bisect uni bo'la olmaydi. Shuning uchun GitHub flow kichik PR'larni talab qiladi (Yaxshi PR tayyorlash darsi).
Diqqat: GitHub ba'zan xato qaytaradi, lekin amalni bajaradi. Kanon jarayonida yangi branch'ning birinchi push'i ikki marta
remote rejected … (Internal Server Error)oldi — qayta push o'tdi.gh pr mergebir marta502 Bad Gatewayqaytardi, lekin keyingi qatorda#12 MERGEDturdi. Qoida: xato kelsa, darhol qaytarmang — avval holatni tekshiring (gh pr view,git ls-remote).
2.5 Kimga mos
GitHub flow — bitta versiya ishlaydigan joyda mos: veb ilova, API, SaaS. Foydalanuvchida eski versiya qolmaydi, hamma doim oxirgisini oladi. vazifalar-api — aynan shunday. Talabi: avtomatik tekshiruvlar (CI) va tez review. CI bo'lmasa, "main doim ishlaydi" degan va'da faqat umid bo'lib qoladi.
Kanonda sinalmaganlar: required status checks (PR'ni CI yashil bo'lmaguncha to'sish) va merge queue — sinov reposida Actions o'chiq edi. Ular haqida GitHub Actions chuqur darsida.
Tekshirib ko'ring: Ruleset'da
required_linear_historyyoqilgan,allowed_merge_methodsda esamergeham bor. Kimdir PR'ni oddiy "Create a merge commit" bilan qo'shmoqchi. Nima bo'ladi?
Javob
Merge commit chiziqli tarixni buzadi, shuning uchun required_linear_history uni rad etadi. Ikki qoida bir-biriga zid — sozlamada faqat squash va rebase qoldirilishi kerak. Kanon ruleset'ida aynan shunday: faqat squash. Bu xabarni Branch himoyasi darsida ko'rgansiz: "Merge commits are not allowed on this repository."
3. Trunk-based development
3.1 Qoidalar
Trunk (tana) — asosiy branch, odatda main. Trunk-based development — hamma o'z ishini tez-tez, kamida kuniga bir marta trunk'ga qo'shadi. Sayt buni shunday yozadi: "all team members commit to trunk at least once every 24 hours". Ya'ni "jamoaning har a'zosi kamida 24 soatda bir marta trunk'ga commit qiladi" (trunkbaseddevelopment.com, 2026-11-04 da o'qildi). Asosiy qoidalar:
- branch'lar qisqa umrli — soatlar, ko'pi bilan bir-ikki kun (sayt aniq muddat yozmaydi, bu son 24 soatlik qoidadan kelib chiqadi); kichik jamoada to'g'ridan trunk'ga commit ham bo'ladi;
- tayyor bo'lmagan xususiyat ham trunk'ga tushadi — feature flag ortida, o'chiq holda (Feature flag'lar backend'da);
- reliz — trunk'dan, istalgan payt; kerak bo'lsa reliz branch'i ham trunk'dan ochiladi, lekin unga kod yozilmaydi.
Asosiy g'oya: birlashtirishni kechiktirmaslik. Branch qancha uzoq yashasa, main bilan farqi shuncha katta, konflikt shuncha og'ir. Trunk-based'da konflikt kichik — chunki farq bir kunlik.
3.2 Kanon tajribasi
Kanon bir xil uchta o'zgarishni (2 ta feat + 1 ta fix) ikki workflow'da yozdi. Trunk-based'da qisqa branch'lar --ff-only bilan qo'shildi va darhol o'chirildi:
git switch -c qidiruv-filtr
# ... commit: feat: qidiruvga filtr (bayroq ortida, o'chiq)
git switch main
git merge --ff-only qidiruv-filtr
git branch -d qidiruv-filtr--ff-only — faqat fast-forward (Merge darsi): main oldinga suriladi, merge commit yaratilmaydi. Agar main orada o'zgargan bo'lsa, buyruq rad etadi — avval rebase kerak. Natijaviy tarix (kanon chiqishi):
* bf02850 (HEAD -> main, tag: v1.1.0) feat: filtr bayrog'i 10% foydalanuvchiga
* bbdecf4 feat: filtr UI (bayroq ortida)
* b74c2fa fix: sana formati
* fda4f88 feat: qidiruvga filtr (bayroq ortida, o'chiq)
* 8b48306 feat: boshlang'ich
branch'lar: 1 (faqat main)Bitta chiziq. Commit xabarlariga qarang: filtr ikki bosqichda, "bayroq ortida" qo'shildi — foydalanuvchi uni ko'rmaydi. Faqat oxirgi commit bayroqni 10% foydalanuvchiga ochadi. Kod tayyor bo'lmasdan trunk'da yashaydi, lekin hech kimni buzmaydi. Bu — 31-qismdagi foizli rollout.
3.3 Narxi
- CI shart. Hamma kuniga bir necha marta
mainga qo'shsa, har qo'shishda testlar yurishi kerak. Aks holdamaintez-tez buziladi. - Feature flag intizomi. Flag'lar to'planib qoladi. Eskirgan flag — o'lik kod. Ularni o'chirish rejasi bo'lsin.
- Review tezligi. PR bir kun kutib qolsa, "qisqa umr" buziladi. Ba'zi jamoalar juft dasturlash (pair programming) bilan review'ni almashtiradi.
4. Git-flow
4.1 Qoidalar
Git-flow — 2010 yil 5 yanvarda Vincent Driessen taklif qilgan model (nvie.com, 2026-11-04 da o'qildi). Unda ikki doimiy branch bor:
main— faqat relizlar, har merge'ga tag;develop— keyingi reliz uchun yig'ilayotgan ish.
Va uch xil vaqtinchalik branch:
feature/*—developdan ochiladi,developga qaytadi;release/*— reliz tayyorlash (versiya raqami, oxirgi tuzatishlar):developdan ochiladi, hammainga, hamdevelopga merge qilinadi;hotfix/*— prodakshndagi shoshilinch xato:maindan ochiladi, yana ikki joyga merge.
Hamma merge'lar --no-ff bilan — har branch tarixda alohida "qavariq" bo'lib ko'rinsin.
gitGraph
commit id: "v1.0.0"
branch develop
branch feature/qidiruv
commit id: "qidiruv"
checkout develop
merge feature/qidiruv
branch release/1.1.0
commit id: "versiya 1.1.0"
checkout main
merge release/1.1.0 tag: "v1.1.0"
checkout develop
merge release/1.1.0Diagramma ataylab soddalashtirildi: bitta feature va reliz. Hotfix ham xuddi reliz kabi ikki joyga qo'shiladi.
4.2 Kanon tajribasi
Xuddi o'sha uchta o'zgarish git-flow bilan: ikkita feature/*, bitta release/1.1.0, bitta hotfix/1.1.1. Grafda Merge branch qatorlarini va chapdagi parallel chiziqlarni sanang. Kanon chiqishi:
* 4d8f501 (HEAD -> develop) Merge branch 'hotfix/1.1.1' into develop
|\
* \ 8b56a77 Merge branch 'release/1.1.0' into develop
|\ \
| | | * d4b3536 (tag: v1.1.1, main) Merge branch 'hotfix/1.1.1'
| | | |\
| | | |/
| | |/|
| | * | 6ed377e fix: eksportda bo'sh qator
| | |/
| | * 649b864 (tag: v1.1.0) Merge branch 'release/1.1.0'
| | |\
| | |/
| |/|
| * | 16badfb chore: versiya 1.1.0
|/ /
* | 885ab15 Merge branch 'feature/eksport' into develop
|\ \
| * | 743ae2b feat: CSV eksport
|/ /
* | 4bb4f00 Merge branch 'feature/qidiruv' into develop
|\ \
| |/
|/|
| * 3c8b819 feat: qidiruv
|/
* 8a368eb (tag: v1.0.0) feat: boshlang'ich
merge commit'lar: 6; doimiy branch'lar: develop main Grafni pastdan yuqoriga o'qing. Ikki feature develop ga qo'shildi. Reliz branch'ida versiya raqami o'zgardi va u main ga (v1.1.0 tagi) va develop ga qo'shildi. Keyin prodakshnda xato topildi: hotfix main dan ochildi, tuzatildi va yana ikki joyga qo'shildi (v1.1.1).
4.3 Narxi va qachon mos
Bir xil ish uchun 11 commit va 6 merge commit — trunk-based'da 5 va 0:
- trunk-based: commit5 ta
- trunk-based: merge commit0 ta
- git-flow: commit11 ta
- git-flow: merge commit6 ta
Manba: IlmHamroh kanon tajribasi, 2026-11-04: Git 2.54.0, bir xil 2 feat + 1 fix; git-flow — 2 feature, 1 release, 1 hotfix branch
Qo'shimcha commitlar o'z-o'zidan yomon emas. Muammo boshqa joyda:
- Ikki joyga merge. Hotfix
mainga qo'shilib,developga unutilsa — keyingi relizda xato qaytadi. Bu git-flow'ning eng ko'p uchraydigan nosozligi. - Uzun branch'lar.
developva reliz branch'lari kunlab, haftalab yashaydi — konfliktlar kattalashadi. - Bisect va o'qish qiyin. Grafni ko'rdingiz: oddiy tarixni tushunish uchun chiziqlarni kuzatish kerak.
Git-flow qachon o'zini oqlaydi? Bir vaqtda bir nechta versiya qo'llab-quvvatlanganda: mobil ilova (do'kondagi 3.2 va tayyorlanayotgan 3.3), desktop dastur, kutubxonaning eski major versiyasi. Modelning muallifi 2020 yil 5 martda maqolasiga "Note of reflection" (mulohaza) qo'shgan. Unda doimiy yetkaziladigan veb ilovalar uchun GitHub flow kabi soddaroq usulni tavsiya qiladi. Git-flow esa aniq versiyalanadigan yoki bir nechta versiyasi qo'llab-quvvatlanadigan dasturga mos, deydi. Yakuniy gapi: "panaceas don't exist" — "hamma dardga davo yo'q, o'z sharoitingizga qarang".
Tekshirib ko'ring: Git-flow'da hotfix faqat
mainga merge qilindi,developga — yo'q. Keyingi relizdevelopdan chiqadi. Nima bo'ladi va buni qanday tekshirish mumkin?
Javob
Keyingi reliz develop dan tayyorlanadi, unda tuzatish yo'q — xato prodakshnga qaytadi. Tekshirish: git branch --contains <hotfix-commit> — commit qaysi branch'larda borligini ko'rsatadi. Ro'yxatda develop bo'lmasa — hotfix unutilgan. Reliz oldidan bunday tekshiruvni avtomatlashtirish mumkin.
5. Taqqoslash
| GitHub flow | Trunk-based | Git-flow | |
|---|---|---|---|
| Doimiy branch'lar | main |
main |
main, develop |
| Branch umri | kunlar | soatlar | haftalar |
| Tayyor bo'lmagan ish | branch'da kutadi | flag ortida main da |
develop da |
| Reliz | har merge yoki tag | istalgan payt | release/* orqali |
Uchala workflow'ni aralashtirish ham mumkin. Ko'p jamoalar GitHub flow'ni trunk-based ruhida ishlatadi: PR'lar kichik, kuniga bir necha marta merge, tayyor bo'lmagan ish flag ortida. Ba'zi jamoalar faqat release/* ni qo'shadi — qo'llab-quvvatlanadigan eski versiya uchun.
6. Branch nomlash
Workflow'ning kichik, lekin muhim qismi — nomlar. Branch nima darsidan boshlab kursda prefikslar ishlatiladi: feature/, fix/, chore/. Kanon sinov reposidagi branch'lar ham shunday edi: fix/31-nuqsonlari, chore/reliz-4.0.1, chore/codeowners, docs/readme, docs/litsenziya.
Yaxshi nom uchta narsani aytadi: tur (prefiks), mazmun (qisqa, kichik harf, chiziqcha bilan) va ixtiyoriy issue raqami (fix/42-sana-formati). Kelishuvni kod bilan tekshirish mumkin:
const NAQSH =
/^(feature|fix|chore|docs|release|hotfix)\/[a-z0-9][a-z0-9.-]*$/;
function branchNomiTogrimi(nom) {
return NAQSH.test(nom);
}
const nomlar = [
"fix/31-nuqsonlari", "chore/reliz-4.0.1", "docs/readme",
"Aziz-branch", "feature/Yangi Filtr", "hotfix/4.0.2",
];
for (const nom of nomlar) {
console.log(nom.padEnd(20), branchNomiTogrimi(nom));
}Konsolda:
fix/31-nuqsonlari true
chore/reliz-4.0.1 true
docs/readme true
Aziz-branch false
feature/Yangi Filtr false
hotfix/4.0.2 trueAziz-branch — prefiks yo'q va nom ishni emas, odamni aytadi. feature/Yangi Filtr — bosh harf va bo'sh joy: terminalda qo'shtirnoqsiz yozib bo'lmaydi. Shunday tekshiruvni ruleset ham qila oladi: ruleset yaratishda "Restrictions" bo'limidagi "Restrict branch names" qoidasi (docs.github.com, "Creating rulesets for a repository", sinalmagan, 2026-11).
7. Loyiha qadami: vazifalar-api uchun GitHub flow
Bu dars — tajriba darsi: loyiha kodi o'zgarmaydi va commit yo'q. Lekin workflow tanlanadi. vazifalar-api uchun kanon GitHub flow ni tanladi:
- API — bitta versiya ishlaydigan veb xizmat; eski versiyalar qo'llab-quvvatlanmaydi.
- Repo'da Branch himoyasi darsidagi ruleset bor: faqat PR, chiziqli tarix, squash.
- Reliz — tag va CHANGELOG (CHANGELOG va reliz avtomatikasi).
- Tayyor bo'lmagan xususiyat — 31-qismda qurilgan flag'lar ortida.
O'z repo'ngizda keyingi ishni shu tartibda boshlang:
git switch main
git pull
git switch -c docs/hissa-qoshishBu branch hozircha mashq uchun: Yaxshi PR tayyorlash darsida uni main ning o'sha paytdagi holatidan qayta boshlaymiz. Nomi esa bejiz emas: 32-qismning jamoa darslarida (CONTRIBUTING.md, PR shabloni) aynan shunday branch'lar ochiladi. Workflow qoidalari esa keyinroq Yaxshi PR tayyorlash darsida CONTRIBUTING.md ga yoziladi — kelishuv faqat boshda emas, hujjatda ham tursin.
8. Ko'p uchraydigan xatolar
8.1 GH013 — to'g'ridan push
Ruleset main ni himoya qiladi: "Changes must be made through a pull request." Davosi: commitni branch'ga ko'chiring (Branch himoyasi darsidagi retsept) va PR oching. --force yechim emas — u ham taqiqlangan.
8.2 Fast-forward bo'lmadi
Trunk-based'da ikkinchi branch'ni --ff-only bilan qo'shmoqchi bo'lsangiz, main esa orada oldinga ketgan bo'lsa, biz shu chiqishni oldik:
hint: Diverging branches can't be fast-forwarded, you need to either:
hint:
hint: git merge --no-ff
hint:
hint: or:
hint:
hint: git rebase
hint:
hint: Disable this message with "git config set advice.diverging false"
fatal: Not possible to fast-forward, aborting."Ajralgan branch'larni fast-forward qilib bo'lmaydi: yo merge commit, yo rebase." Trunk-based'da tanlov — rebase: branch'ni main ustiga ko'chirasiz va yana --ff-only. Buni 3-mashqda qilasiz.
8.3 Uzoq yashovchi branch
Branch bir hafta yashadi, main 40 commit oldinga ketdi, PR'da 15 ta konflikt. Davosi — oldini olish: ishni kichik qismlarga bo'ling, har kuni main ni branch'ga olib turing (git rebase main), tayyor bo'lmaganini flag ortida qo'shing.
8.4 "Can not approve your own pull request"
Bitta odamli repoda tasdiq talabi qo'ysangiz, hech narsani merge qila olmaysiz. Jamoada bu to'g'ri xulq — o'z kodini o'zi tasdiqlamaydi.
8.5 Hotfix bir joyga
Git-flow'da hotfix develop ga qo'shilmadi. Davosi: git branch --contains <commit> bilan tekshirish va har hotfix'ni ikki merge bilan yopish.
9. Mashqlar
Mashqlar kurs/mashqlar/32/03-workflow/ da. 2-mashq yechimi Node 24.21.0 da, 3-mashq yechimi Git 2.54.0 da tekshirilgan (biz ishga tushirdik).
1-mashq (oson): bo'shliqlarni to'ldiring
- Git-flow'da keyingi reliz uchun ish yig'iladigan doimiy branch —
- Prodakshndagi shoshilinch xato uchun git-flow branch'i prefiksi —
- Merge commit yaratmay, faqat
mainni oldinga suradigan bayroq —git merge -- - Trunk-based'da tayyor bo'lmagan xususiyat nima ortida yashaydi? —
- Kanon ruleset'ida ruxsat etilgan yagona merge usuli —
Yechim
- develop —
mainesa faqat relizlar. - hotfix —
maindan ochiladi va ikki joyga qo'shiladi. - ff-only —
mainajralgan bo'lsa, rad etadi. - feature flag — kod
mainda, lekin foydalanuvchiga o'chiq. - squash — PR bitta commitga siqiladi, tarix chiziqli qoladi.
2-mashq (o'rta): eski branch'larni topish
Trunk-based'da branch ko'pi bilan 2 kun yashashi kerak. eskiBranchlar(branchlar, bugun, chegaraKun) funksiyasini yozing. branchlar — { nom, ochilgan } obyektlari (ochilgan — ISO sana satri). Funksiya chegaradan uzoq yashagan branch'larni "nom: N kun" ko'rinishida, eng eskisidan boshlab qaytarsin. main hisobga olinmasin. Ishora: ikki sana farqi millisekundda — new Date(a) - new Date(b); kun — 86_400_000 ms (Date asoslari); butun kun uchun Math.floor.
Yechim
const KUN = 86_400_000;
function eskiBranchlar(branchlar, bugun, chegaraKun) {
return branchlar
.filter((b) => b.nom !== "main")
.map((b) => ({
nom: b.nom,
kun: Math.floor((new Date(bugun) - new Date(b.ochilgan)) / KUN),
}))
.filter((b) => b.kun > chegaraKun)
.sort((a, b) => b.kun - a.kun)
.map((b) => `${b.nom}: ${b.kun} kun`);
}
const branchlar = [
{ nom: "main", ochilgan: "2026-09-30T10:00:00+05:00" },
{ nom: "fix/sana", ochilgan: "2026-11-03T15:00:00+05:00" },
{ nom: "feature/eksport", ochilgan: "2026-10-21T09:00:00+05:00" },
{ nom: "feature/filtr", ochilgan: "2026-11-01T09:00:00+05:00" },
];
console.log(eskiBranchlar(branchlar, "2026-11-04T12:00:00+05:00", 2));Konsolda:
[ 'feature/eksport: 14 kun', 'feature/filtr: 3 kun' ]fix/sana bir kunga ham to'lmagan — normal. feature/filtr uch kunlik — chegaradan o'tdi, uni kichik qismlarga bo'lish yoki flag ortida qo'shish vaqti keldi. feature/eksport ikki hafta yashagan — bunday branch'ning PR'i katta konflikt bilan keladi. Haqiqiy repoda sana git log -1 --format=%cI <branch> dan olinadi.
3-mashq (qiyin): ikki dasturchi, bitta trunk
kurs/mashqlar/32/03-workflow/trunk-yarat.sh repo yaratadi: main da bitta commit, undan ikkita qisqa branch — feature/filtr (Aziz) va fix/sana (Nodira). Vazifa: ikkalasini main ga faqat fast-forward bilan qo'shing, merge commit bo'lmasin, oxirida faqat main qolsin.
bash trunk-yarat.sh trunkvacd trunk.feature/filtrni--ff-onlybilan qo'shing.fix/sanani ham shunday qo'shishga urining — nima bo'ladi?- Muammoni rebase bilan yeching va qayta qo'shing.
- Ikkala branch'ni o'chiring,
git log --graphva merge commitlar sonini ko'rsating.
Ishora: Rebase darsi — git rebase main branch'ni main ustiga ko'chiradi. SHA'lar darsdagidek chiqishi uchun rebase'dan oldin committer'ni qotiring: export GIT_COMMITTER_NAME="Nodira Rahimova" GIT_COMMITTER_EMAIL="nodira@example.com" GIT_COMMITTER_DATE="2026-11-02T11:00:00+05:00".
Yechim
bash trunk-yarat.sh trunk && cd trunk
export GIT_COMMITTER_NAME="Nodira Rahimova"
export GIT_COMMITTER_EMAIL="nodira@example.com"
export GIT_COMMITTER_DATE="2026-11-02T11:00:00+05:00"
git merge -q --ff-only feature/filtr
git merge --ff-only fix/sana
git switch -q fix/sana
git rebase -q main
git switch -q main
git merge -q --ff-only fix/sana
git branch -q -d feature/filtr fix/sana
git log --graph --format='%h %an: %s'
echo "merge commitlar: $(git rev-list --merges --count HEAD)"
echo "branch'lar: $(git branch --format='%(refname:short)')"Biz ishga tushirdik (trunk-yarat.sh chiqishi yozilmagan):
hint: Diverging branches can't be fast-forwarded, you need to either:
hint:
hint: git merge --no-ff
hint:
hint: or:
hint:
hint: git rebase
hint:
hint: Disable this message with "git config set advice.diverging false"
fatal: Not possible to fast-forward, aborting.
* ff24e9e Nodira Rahimova: fix: sana formati
* 460a757 Aziz Karimov: feat: qidiruvga filtr (bayroq ortida, o'chiq)
* 3ab7b6b Aziz Karimov: feat: boshlang'ich
merge commitlar: 0
branch'lar: mainBirinchi qo'shish o'tdi — main oldinga surildi. Ikkinchisi rad etildi: fix/sana eski main dan ochilgan, endi ikki tarix ajralgan. Rebase Nodira commitini yangi main ustiga ko'chirdi (yangi SHA, chunki ota-commit o'zgardi) va --ff-only o'tdi. Natija — uchta commit bir chiziqda, merge commit 0. Bu — trunk-based'ning kichik nusxasi. GitHub'da "Rebase and merge" yoki squash tugmasi xuddi shu ishni server tomonida qiladi.
10. Real ishda
- Qayerda uchraydi: startap va SaaS jamoalarining ko'pi — GitHub flow yoki trunk-based. Git-flow — mobil ilovalar, desktop dasturlar, bir nechta versiyani qo'llab-quvvatlaydigan kutubxonalar.
- DORA (DevOps Research and Assessment — jamoalar dasturni qanchalik tez va barqaror yetkazishini yillar davomida o'lchaydigan tadqiqot dasturi). Uning sahifasiga ko'ra, 2016–2017 ma'lumotlarida trunk-based amaliyotiga amal qilgan jamoalar yetkazish tezligi va barqarorligida yuqoriroq natija ko'rsatgan. Tavsiyalari aniq: repo'da uchtadan ko'p bo'lmagan faol branch, branch'larni kamida kuniga bir marta trunk'ga qo'shish (dora.dev, 2026-11-04 da o'qildi).
- Intervyu savollari: "Jamoangizda qanday branching strategiyasi bor va nega?", "Git-flow va trunk-based farqi?", "Hotfix qanday o'tadi?", "Uzoq yashovchi branch'lar muammosini qanday hal qilasiz?"
Xulosa
- Workflow — branch'lar bo'yicha jamoaviy kelishuv: qayerdan, qancha, qayerga, reliz qanday.
- GitHub flow:
maindoim tayyor, har ish — qisqa branch va PR; ruleset uni server darajasida majburlaydi. - Trunk-based: branch'lar soatlab yashaydi, tayyor bo'lmagan ish feature flag ortida; CI shart.
- Git-flow:
main+develop, release/hotfix ikki joyga merge; bir nechta versiya qo'llab-quvvatlansa o'zini oqlaydi. - Kanon: bir xil 3 o'zgarish — trunk-based 5 commit / 0 merge, git-flow 11 / 6; sinov reposida 10 PR, chiziqli
main. - Branch nomi:
tur/qisqa-mazmun, kichik harf, chiziqcha.
Keyingi dars: Commit imzolash va Verified belgisi — user.email ni istalgan kishi yozishi mumkin; SSH imzo bilan commit muallifi haqiqatan siz ekaningizni isbotlaymiz.
Manbalar
- GitHub Docs — GitHub flow: https://docs.github.com/en/get-started/using-github/github-flow (2026-11-04 da o'qildi)
- GitHub Docs — Available rules for rulesets: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets (2026-11-04 da o'qildi)
- GitHub Docs — Creating rulesets for a repository ("Restrict branch names"): https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/creating-rulesets-for-a-repository (sinalmagan, 2026-11)
- Trunk Based Development: https://trunkbaseddevelopment.com/ (2026-11-04 da o'qildi)
- Vincent Driessen — A successful Git branching model: https://nvie.com/posts/a-successful-git-branching-model/ (2026-11-04 da o'qildi)
- DORA — Trunk-based development: https://dora.dev/capabilities/trunk-based-development/ (2026-11-04 da o'qildi)
- Git hujjati — git-merge (
--ff-only): https://git-scm.com/docs/git-merge - Kanon tajribasi (IlmHamroh, 2026-11-04): Git 2.54.0, gh 2.92.0; trunk-based va git-flow tarixlari, sinov reposidagi ruleset, GH013, PR #9 rad etishlari.
--ff-onlychiqishi va mashq yechimlari — biz ishga tushirdik (2026-11-04).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!