4.2-bob: Branch, merge, rebase, conflict yechish
4-QISM — Git va hamkorlik · 2-mavzu
1. Kirish va motivatsiya
Asosiy Git siklini 4.1-bob bildik — lekin u chiziqli edi (bitta yo'nalishda commit'lar). Real ishda esa parallel ishlash kerak: siz yangi feature yozayotganingizda, hamkasbingiz xato tuzatadi, boshqasi boshqa feature ustida — hammasi bir vaqtda, bir-biriga xalaqit bermasdan. Branch (tarmoq) aynan shuni beradi.
Branch — asosiy koddan ajralib chiqib, alohida "parallel olam"da ishlash. Yangi feature'ni branch'da xavfsiz yozasiz; tayyor bo'lsa — asosiy kodga birlashtirasiz (merge). Asosiy kod doim ishlaydigan, barqaror holatda qoladi.
O'xshatish: branch — daryoning shoxobchasi. Asosiy daryo (
main) — barqaror oqim. Yangi g'oya uchun shoxobcha (branch) ochasiz, unda erkin tajriba qilasiz (asosiy daryoga ta'sir qilmaydi). Muvaffaqiyatli bo'lsa — shoxobchani asosiy daryoga qaytarasiz (merge). Yomon bo'lsa — shoxobchani tashlab yuborasiz (asosiy daryo zarar ko'rmaydi).
Nega muhim?
- Parallel ish — bir necha feature/dasturchi bir vaqtda (4.3: hamkorlik).
- Xavfsiz tajriba —
maindoim barqaror; branch'da erkin sinang. - Pull Request 4.3-bob — branch'ni ko'rib chiqib birlashtirish.
- Git workflow'lar 4.4-bob — branch strategiyasiga asoslanadi.
2. Nazariya — chuqur tushuntirish
2.1. Branch nima?
Branch — commit'lar zanjiridagi ko'rsatkich (pointer — 3.3). main — default branch (asosiy). Yangi branch yaratganda — yangi ko'rsatkich; unda commit qilsangiz, faqat shu branch oldinga siljiydi, main joyida qoladi:
main
│
A───B───C
\
D───E feature branch (yangi commit'lar)
│
featureBranch — arzon: Git'da branch faqat ko'rsatkich (40-baytli hash — 3.5), shuning uchun yaratish bir lahza. Boshqa VCS'larda branch — butun nusxa (qimmat). Git'da branch'ni erkin ishlating.
2.2. HEAD — qayerda turibmiz?
HEAD — hozir qaysi branch/commit'da turganingizni ko'rsatadigan maxsus ko'rsatkich. git checkout/git switch bilan branch'lar orasida o'tganda, HEAD ko'chadi va working directory 4.1-bob o'sha branch holatiga o'zgaradi.
HEAD'dan orqaga yurish. Ko'p buyruqlar (reset, rebase, diff) commit'ni HEAD'ga nisbatan ko'rsatishni qulaylashtiradi. ~ (tilde) — necha commit orqaga, ^ (caret) — qaysi ota (merge'da ikki ota bo'ladi):
git log HEAD~1 # HEAD'dan 1 commit oldingi (bitta otasi)
git log HEAD~3 # HEAD'dan 3 commit orqada
git log HEAD^ # HEAD ning otasi (= HEAD~1)
git log HEAD^2 # merge commit'ning 2-otasi (qo'shilgan branch)
~vs^:HEAD~N— chiziq bo'ylab N qadam orqaga (har doim birinchi ota).HEAD^N— N-otani tanlash (faqat merge commit'da farq qiladi, chunki oddiy commit'ning bitta otasi bor). Kundalik ishda ko'pinchaHEAD~1,HEAD~2kifoya.
Detached HEAD (ajralgan HEAD). Agar branch nomiga emas, to'g'ridan-to'g'ri commit hash'iga o'tsangiz (git checkout <hash>), HEAD branch'ga emas, commit'ga "yopishadi" — bu detached HEAD holati. Bu yerda yangi commit qilsangiz, ular hech qaysi branch'ga bog'lanmaydi va boshqa branch'ga o'tsangiz yo'qolib qolishi mumkin:
git checkout a1b2c3d # eski commit'ni ko'rish uchun o'tdik
# "You are in 'detached HEAD' state" ogohlantirishi chiqadi
# faqat ko'rish (read-only) uchun — xavfsiz
# Agar bu yerda ishni davom ettirmoqchi bo'lsangiz — DARROV branch yarating:
git switch -c eksperiment # hozirgi holatdan yangi branch (ish saqlanadi)Detached HEAD — vahima qilmang. U "branch'da emas, commit'da turibsiz" degani — eski holatni ko'rish uchun normal. Faqat yangi ish boshlasangiz,
git switch -c <nom>bilan branch'ga "biriktiring", aks holda commit'lar yo'qolishi mumkin.
2.3. Branch buyruqlari
git branch # branch'lar ro'yxati (joriy * bilan)
git branch feature-login # yangi branch yaratish (o'tmasdan)
git switch feature-login # branch'ga o'tish (zamonaviy)
git switch -c feature-login # yaratish + o'tish (birga) — eng ko'p
git checkout feature-login # o'tish (eski usul, hali ishlaydi)
git checkout -b feature-login # yaratish + o'tish (eski)
git branch -d feature-login # branch o'chirish (merge qilingach)
git branch -D feature-login # majburan o'chirish (merge qilinmagan)
switchvscheckout:switch— zamonaviy, faqat branch uchun (aniqroq).checkout— eski, ko'p vazifali (branch + fayl restore — 4.1). Yangi koddaswitchafzal.
2.4. Merge — birlashtirish
Merge — branch'dagi o'zgarishlarni boshqa branch'ga (odatda main) qaytarib qo'shish:
git switch main # avval qabul qiluvchi branch'ga o't
git merge feature-login # feature'ni main'ga birlashtirIkki turdagi merge:
Fast-forward — main o'zgarmagan bo'lsa, shunchaki ko'rsatkichni oldinga suradi (toza, yangi commit yo'q):
main main
│ merge │
A───B + C───D A───B───C───D (chiziqli)3-way merge — ikkalasi ham o'zgargan bo'lsa, yangi merge commit yaratadi:
A───B───C (main) A───B───C───M (M — merge commit)
\ \ /
D───E (feature) D───E2.5. Rebase — tarixni qayta yozish
Rebase — branch commit'larini boshqa branch uchiga ko'chirish (qayta asoslash). Natija — chiziqli, toza tarix (merge commit'siz):
Merge: Rebase:
A───B───C───M A───B───C───D'───E'
\ / (feature commit'lari
D───E C uchiga ko'chirildi)git switch feature
git rebase main # feature commit'larini main uchiga ko'chirMerge vs Rebase:
- Merge — tarixni saqlaydi (nima qachon bo'lganini ko'rsatadi), merge commit qo'shadi. Xavfsiz.
- Rebase — tarixni qayta yozadi (chiziqli, toza), lekin tarixni o'zgartiradi.
Oltin qoida: public (push qilingan, boshqalar ishlayotgan) branch'ni rebase qilmang! Bu boshqalarning tarixini buzadi. Rebase faqat o'zingizning lokal branch'ingiz uchun.
Interaktiv rebase (-i) — tarixni tahrirlash. Rebase'ning yana bir kuchli ishlatilishi — push qilishdan oldin o'z lokal commit'laringizni tozalash: bir nechtasini birlashtirish, xabarlarni tuzatish, keraksizini olib tashlash. git rebase -i <baza> muharrir ochadi va har commit yonida amal tanlanadi:
git rebase -i HEAD~3 # oxirgi 3 commit'ni interaktiv tahrirlashpick a1b2c3 Login formasi
squash 4d5e6f Tugma rangini tuzatdim # oldingiga qo'shib yuboriladi
reword 7g8h9i login # commit xabari qayta yoziladiAsosiy amallar (muharrirdagi har bir qator boshida):
pick— commit'ni o'zgarishsiz qoldirish (default).squash/s— commit'ni oldingisiga birlashtirish (xabarlar qo'shiladi).fixup/f— squash kabi, lekin bu commit xabarini tashlab yuboradi.reword/r— commit'ni saqlash, lekin xabarini qayta yozish.drop/d— commit'ni butunlay olib tashlash.- Qatorlar o'rnini almashtirib, commit'lar tartibini ham o'zgartirishingiz mumkin.
Nega kerak? Ish jarayonida "WIP", "tuzatdim", "yana tuzatdim" kabi tartibsiz commit'lar to'planadi. Push 4.3-bob qilishdan oldin ularni
squashbilan bitta mazmunli commit'ga jamlasangiz, tarix toza va o'qishli bo'ladi. Bu ham tarixni qayta yozadi — shuning uchun Oltin qoida amal qiladi: faqat push qilinmagan commit'larda ishlating.
2.6. Cherry-pick — bitta commit'ni ko'chirish
Cherry-pick — boshqa branch'dagi bitta (yoki bir nechta) aniq commit'ni joriy branch'ga nusxalash. Butun branch'ni emas, faqat kerakli commit'ni olib kelasiz:
git switch main
git cherry-pick a1b2c3d # a1b2c3d commit'ini main'ga nusxalash A───B───C (main) A───B───C───E' (E' — nusxa)
\ \
D───E (feature) D───E (feature — joyida qoladi)Qachon kerak? Masalan, hotfix branch'da qilingan bitta tuzatish commit'ini boshqa branch'ga ham olib o'tish kerak bo'lsa — butun branch'ni merge qilmasdan, aynan o'sha commit'ni cherry-pick qilasiz.
Diqqat: cherry-pick commit'ni nusxalaydi (yangi hash bilan), ko'chirmaydi — asl commit o'z branch'ida qoladi. Ikki branch'da bir xil o'zgarish ikki marta paydo bo'lishi keyin merge'da chalkashlik tug'dirishi mumkin, shuning uchun zarur bo'lgandagina ishlating.
2.7. Conflict (ziddiyat) — qachon va nega
Merge conflict — ikki branch bir xil faylning bir xil qatorini har xil o'zgartirganda yuzaga keladi. Git qaysi birini olishni bilmaydi va sizdan so'raydi:
main'da: const rang = "ko'k";
feature'da: const rang = "qizil";
merge CONFLICT! Git: "qaysi birini olay?"Git faylga ikkala variantni belgilab qo'yadi:
<<<<<<< HEAD
const rang = "ko'k"; // main'dagi (joriy)
=======
const rang = "qizil"; // feature'dagi (kelayotgan)
>>>>>>> feature2.8. Conflict'ni yechish
# 1. merge/rebase conflict berdi
git status # qaysi fayllar conflictli ko'rsatadi
# 2. Faylni OCH, <<<<< ===== >>>>> belgilarini TOP (2.7)
# Kerakli variantni qoldir, belgilarni O'CHIR, kodni to'g'rila
# 3. Yechilgan faylni belgila
git add <fayl>
# 4. Yakunlash
git commit # merge uchun (xabar avtomatik)
# yoki rebase uchun:
git rebase --continueConflict — normal, qo'rqmang. U "ikki kishi bir joyni o'zgartirgan" degani. Belgilarni o'chirib, to'g'ri kodni qoldiring. Chalkashsa —
git merge --abort/git rebase --abortbilan bekor qiling.
2.9. Branch ishlash sikli (amaliy)
1. git switch -c feature-x # main'dan yangi branch
2. (kod yoz, commit qil) # 4.1 sikli
3. git switch main # main'ga qayt
4. git merge feature-x # birlashtir (yoki PR — 4.3)
5. git branch -d feature-x # branch'ni o'chir (tugadi)3. Sintaksis — tez ma'lumotnoma
# Branch
git branch # ro'yxat
git switch -c <nom> # yarat + o't
git switch <nom> # o't
git branch -d <nom> # o'chir
# Birlashtirish
git merge <branch> # merge (xavfsiz, tarix saqlanadi)
git rebase <branch> # rebase (chiziqli, public'da QILMA)
git rebase -i HEAD~N # interaktiv: squash/reword/drop (2.5)
git cherry-pick <hash> # bitta commit'ni nusxalash (2.6)
# Navigatsiya
git switch -c <nom> <hash> # eski commit'dan branch (detached HEAD — 2.2)
git log HEAD~2 # HEAD'dan 2 commit orqaga (2.2)
# Conflict
git status # conflictli fayllar
# <<<<< ===== >>>>> yech git add git commit / git rebase --continue
git merge --abort # bekor qilish4. Batafsil amaliy namunalar
Misol 1 — Feature branch sikli (2.9)
git switch -c feature-login # yangi branch (2.3)
echo "login kodi" > login.js
git add login.js
git commit -m "Login sahifasi qo'shildi"
git switch main # main'ga qayt
git merge feature-login # birlashtir (2.4)
git branch -d feature-login # branch tugadi, o'chir
git log --oneline --graph # tarixni ko'r (4.1)Misol 2 — Parallel ish (ikki branch — 2.1)
# Feature ustida ishlayapmiz
git switch -c feature-profil
echo "profil" > profil.js && git add . && git commit -m "Profil sahifasi"
# Shoshilinch xato chiqdi — main'da tuzatamiz (feature'ga tegmasdan)
git switch main
git switch -c hotfix-bug
echo "tuzatish" > fix.js && git add . && git commit -m "Kritik xato tuzatildi"
git switch main && git merge hotfix-bug # tuzatish darrov main'ga
# Keyin feature'ni davom ettiramiz (xalaqit bo'lmadi)
git switch feature-profilMisol 3 — Conflict yechish (2.7, 2.8)
# main'da rang.js: const rang = "ko'k"
git switch -c feature-rang
# feature'da: const rang = "qizil" qildik, commit
git switch main
# main'da ham o'zgartirdik: const rang = "yashil", commit
git merge feature-rang
# CONFLICT! rang.js'da:
# <<<<<<< HEAD
# const rang = "yashil";
# =======
# const rang = "qizil";
# >>>>>>> feature-rang
# Faylni ochib, kerakligini qoldiramiz (masalan "qizil"), belgilarni o'chiramiz:
# const rang = "qizil";
git add rang.js
git commit -m "rang merge: qizil tanlandi" # conflict yechildiMisol 4 — Rebase bilan toza tarix (2.5)
git switch feature-x
git rebase main # feature commit'larini main uchiga ko'chir
# (conflict bo'lsa: yech git add git rebase --continue)
git switch main
git merge feature-x # endi fast-forward (chiziqli — 2.4)
git log --oneline --graph # toza, chiziqli tarix5. To'g'ri va noto'g'ri holatlar
1) mainda to'g'ridan-to'g'ri ishlash
# main'da to'g'ridan ishlab, barqarorlikni buzish
git switch main && (kod yoz) && git commit
# feature branch'da (main barqaror qoladi — 2.9)
git switch -c feature-x && (kod yoz) && git commit2) Public branch'ni rebase qilish
# boshqalar ishlayotgan branch'ni rebase — tarixni buzadi (2.5)
git rebase main # (push qilingan, umumiy branch'da)
# rebase faqat lokal, push qilinmagan branch'da3) Conflict belgilarini qoldirish
// <<<<< ===== >>>>> belgilarini o'chirmasdan commit (kod buziladi — 2.7)
// belgilarni o'chir, faqat to'g'ri kodni qoldir (2.8)4) Merge qilinmagan branch'ni majburan o'chirish
# -D bilan tasodifan ishni yo'qotish
git branch -D feature-muhim # (merge qilinmagan!)
# -d (merge qilingach); -D faqat ataylab tashlanadigan branch6. Keng tarqalgan xatolar va yechimlari
Xato 1 — CONFLICT (content): Merge conflict in ...
Sababi: ikki branch bir qatorni o'zgartirgan 2.7-bob. Yechimi: faylni oching, <<<<</>>>>> belgilarini yeching, git add, git commit 2.8-bob.
Xato 2 — error: Your local changes would be overwritten
Sababi: saqlanmagan o'zgarishlar branch o'tishga xalaqit. Yechimi: git commit yoki git stash (vaqtincha saqlash), keyin git switch.
Xato 3 — fatal: A branch named 'x' already exists
Sababi: o'sha nomli branch bor. Yechimi: boshqa nom yoki mavjudiga git switch x (yaratmasdan).
Xato 4 — Adashib boshqa branch'da commit qildim
Sababi: noto'g'ri branch'da ish. Yechimi: git log bilan tekshiring; commit'ni to'g'ri branch'ga ko'chirish (cherry-pick — 2.6) yoki ehtiyot bilan reset.
Xato 5 — Rebase chalkashib ketdi
Sababi: ko'p conflict, murakkab rebase. Yechimi: git rebase --abort — boshlang'ich holatga qayting; merge bilan urinib ko'ring.
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- Git asoslari 4.1-bob: branch — commit'lar ustiga quriladi.
- Pull Request 4.3-bob: branch'ni ko'rib chiqib merge.
- Git workflow 4.4-bob: Gitflow/trunk — branch strategiyasi.
- CI/CD 10.5-bob: PR/branch'da avtomatik test.
- Linked list 3.3-bob: branch — commit zanjiriga ko'rsatkich.
- Hamkorlik: parallel ish — branch'ning asosiy maqsadi.
- Conflict — DP/LCS 3.12-bob: git diff/merge ichida matn taqqoslash.
8. Eng yaxshi amaliyotlar (best practices)
- Har feature/tuzatish — alohida branch (
mainda to'g'ridan ishlamang — 2.9). - Mazmunli branch nomlari (
feature-login,fix-auth,hotfix-...). mainni doim barqaror tuting — faqat tayyor, sinalgan kod merge.- Rebase faqat lokal branch'da (public'da qilmang — 2.5).
- Conflict'dan qo'rqmang — belgilarni yeching, to'g'ri kodni qoldiring 2.8-bob.
- Kichik, qisqa umrli branch'lar — uzoq yashagan branch ko'p conflict beradi.
- Merge'dan oldin
mainni yangilang (4.3:git pull) — conflict kamayadi. - Branch'ni merge'dan keyin o'chiring (
-d) — tartib.
9. Amaliy loyiha: "Branch bilan Parallel Ishlash"
Branch, merge, rebase va conflict yechishni amalda mustahkamlash.
Maqsad
Feature branch sikli, merge turlari, conflict yechish va rebase'ni o'zlashtirib, parallel ishlashni simulyatsiya qilish.
Talablar (requirements)
- Asosiy loyiha 4.1-bob —
mainda bir necha commit. - Feature branch:
git switch -cbilan, unda 2-3 commit, keyinmainga merge (fast-forward — Misol 1). - Parallel branch'lar: ikki feature branch bir vaqtda; har birida ish; ikkalasini ham merge (3-way merge — 2.4, Misol 2).
- Conflict yaratish va yechish: ikki branch bir faylning bir qatorini o'zgartirsin; merge conflict yech (Misol 3).
- Hotfix: feature ustida ishlayotib,
mainga shoshilinch tuzatish (alohida branch — Misol 2). - Rebase: bitta branch'ni
mainuchiga rebase qilib, chiziqli tarix (Misol 4); merge bilan farqini ko'ring. - Tarix:
git log --oneline --graph --allbilan barcha branch va merge'larni vizual ko'ring. - Branch'larni merge'dan keyin o'chiring (
-d).
Maslahatlar (hint)
git switch -c <nom>— yarat + o't 2.3-bob.- Conflict: faylni oching,
<<<<</>>>>>yeching,git add,git commit2.8-bob. - Rebase:
git switch feature && git rebase main2.5-bob. git log --graph --all— barcha branch'lar vizual.- Chalkashsa:
git merge --abort/git rebase --abort. - Rebase faqat lokal branch'da 2.5-bob.
"Tayyor" mezonlari (acceptance criteria)
- Feature branch yaratish/merge/o'chirish ishlaydi.
- Fast-forward va 3-way merge ikkalasi ham ko'rsatilgan.
- Conflict ataylab yaratilgan va to'g'ri yechilgan.
- Hotfix parallel branch bilan ko'rsatilgan.
- Rebase bilan chiziqli tarix olingan; merge bilan farqi tushunilgan.
-
git log --graphtoza tarix ko'rsatadi. - Tugagan branch'lar o'chirilgan.
Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.
10. Xulosa va keyingi bobga ko'prik
Bu bobda Git'ning eng kuchli imkoniyatini — branchni o'rgandik:
- Branch — commit zanjiriga ko'rsatkich (arzon); parallel, xavfsiz ish. HEAD — qayerdaligimiz.
git switch -c(yarat+o't),git merge(birlashtir),git branch -d(o'chir).- Merge: fast-forward (chiziqli) yoki 3-way (merge commit). Rebase: chiziqli, toza tarix — lekin public branch'da qilmang.
- Conflict — ikki branch bir qatorni o'zgartirganda;
<<<<</>>>>>belgilarini yechib,git add+ commit. - Interaktiv rebase (
-i) — push'dan oldin commit'larni tozalash (squash/reword/drop). Cherry-pick — bitta commit'ni boshqa branch'ga nusxalash. - HEAD navigatsiya —
HEAD~N/HEAD^bilan orqaga; commit hash'iga o'tsangiz — detached HEAD (ish saqlash uchun branch yarating). - Best: har feature alohida branch,
mainbarqaror, kichik branch'lar.
Keyingi bob — 4.3-bob: GitHub — remote, push, pull, Pull Request, fork. Lokal Git'ni bildik; endi uni bulutga (GitHub) ulaymiz: kodni yuklash (push), olish (pull), va eng muhimi — Pull Request (kodni ko'rib chiqib birlashtirish — jamoaviy ishning yuragi).
Foydalanilgan rasmiy/ishonchli manbalar
- git-scm.com — branch, merge, rebase rasmiy hujjatlari
- Atlassian Git Tutorial — merge vs rebase, conflict resolution
- Pro Git kitobi — branching model
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!