Mundarija (31)
- Bu darsda
- 1. Nega bu kerak?
- 2. Fast-forward: ko'rsatkichni surish
- 2.1 Vaziyat
- 2.2 Merge
- 2.3 Aslida nima bo'ldi?
- 2.4 Ikkinchi marta merge
- 3. Uch tomonlama merge
- 3.1 Tarix ayrilgan bo'lsa
- 3.2 Merge base — umumiy ajdod
- 3.3 Merge commit xabari
- 3.4 Natija — ikki otali commit
- 3.5 Faqat asosiy chiziq: --first-parent
- 4. --no-ff: har doim merge commit
- 4.1 Muammo
- 4.2 Yechim
- 4.3 Qaysi biri yaxshi?
- 5. Ko'p uchraydigan xatolar
- 5.1 Noto'g'ri yo'nalish
- 5.2 Branch nomida xato
- 5.3 Saqlanmagan o'zgarish
- 5.4 Merge commit xabarini bo'sh qoldirish
- 5.5 "Merge — branch'ni o'chiradi"
- 6. Mashqlar
- 1-mashq (oson): Fast-forward yoki merge commit?
- 2-mashq (o'rta): Bo'sh joylarni to'ldiring
- 3-mashq (qiyin): Otalarni toping
- 4-mashq: Portfolio qadami — birinchi merge
- 7. Real ishda
- Xulosa
- Manbalar
Git merge: fast-forward va uch tomonlama birlashtirish
Qisqacha:
git merge <branch>boshqa branch'dagi ishni joriy branch'ga qo'shadi. Agar joriy branch o'sha vaqtda oldinga ketmagan bo'lsa, Git shunchaki ko'rsatkichni suradi — bu fast-forward. Ikkala tomonda ham yangi commit bo'lsa, Git umumiy ajdod (merge base) va ikki uchni solishtirib, ikki otali merge commit yaratadi.--no-ffhar doim merge commit qiladi,--ff-onlyesa faqat fast-forward'ga ruxsat beradi.
Bu darsda
git mergebilan branch'dagi ishnimainga qo'shasiz.- Fast-forward va uch tomonlama birlashtirishni natijasidan ajrata olasiz.
- Merge base nima ekanini va Git uni nega qidirishini tushuntirasiz.
- Merge commitning ikki otasini
git cat-filebilan o'z ko'zingiz bilan ko'rasiz. --no-ffva--ff-onlyni qachon ishlatishni bilasiz.
Oldin bilishingiz kerak: Branch nima: arzon ko'rsatkich, Git ichkaridan: obyektlar, SHA va snapshot, Tarixni o'qish: git log.
1. Nega bu kerak?
Oldingi darsda «Bahor» tarixi ikkiga bo'lindi. main da shashlik narxi bor, feature/bron-forma da esa forma. Forma tayyor. Endi u saytga — ya'ni main ga — chiqishi kerak.
Branch'ning butun ma'nosi shu: alohida ishlash, keyin birlashtirish. Birlashtira olmasak, branch yarim ish bo'lib qoladi. Git'da bu ishni git merge qiladi.
Ikki ariqni tasavvur qiling. Bir ariq ikkinchisidan ajralib, bir oz yurib, yana qo'shiladi. Qo'shilish joyida ikkala ariqning suvi birga oqadi. Merge ham shunday: ikki chiziqdagi o'zgarishlar bitta chiziqqa tushadi.
Git buni ikki xil yo'l bilan qiladi. Qaysi yo'lni tanlashini o'zi hal qiladi — tarixning shakliga qarab. Ikkalasini ham ko'rib chiqamiz.
2. Fast-forward: ko'rsatkichni surish
2.1 Vaziyat
Oldingi darsning mashqida aloqa sahifasiga manzil yozish uchun fix/aloqa-manzil branch'ini ochgan edik. Buni «Bahor»da qilmagan bo'lsangiz, hozir qiling:
cd ~/kurs/bahor
git switch -c fix/aloqa-manzil
echo "<p>Manzil: Toshkent, Bahor ko'chasi 7</p>" >> aloqa/index.html
git add aloqa/index.html
git commit -m "Aloqa: manzilni qo'sh"
git switch mainSwitched to a new branch 'fix/aloqa-manzil'
[fix/aloqa-manzil bba9aee] Aloqa: manzilni qo'sh
1 file changed, 1 insertion(+)
Switched to branch 'main'Tarixga qaraymiz:
git log --oneline --graph --all* bba9aee (fix/aloqa-manzil) Aloqa: manzilni qo'sh
* 297cd7e (HEAD -> main) Menyu: shashlik narxini qo'sh
| * d6772a4 (feature/bron-forma) Bron: telefon maydonini qo'sh
| * 108e327 Bron: formani qo'sh
|/
* 1db8b60 Rasm: choy suratini qo'sh
* 56b3259 Menyu: somsa narxini qo'sh
...(Pastki qatorlar o'zgarmagani uchun ... bilan qisqartirdik.) Diqqat qiling: fix/aloqa-manzil main bilan bitta chiziqda, undan bir qadam oldinda. main o'sha branch ochilgandan beri joyidan qo'zg'almagan.
2.2 Merge
Qoida: siz qaysi branch'da tursangiz, ish o'sha branch'ga qo'shiladi. Biz main damiz va fix/aloqa-manzil ni unga olib kelamiz:
git merge fix/aloqa-manzilUpdating 297cd7e..bba9aee
Fast-forward
aloqa/index.html | 1 +
1 file changed, 1 insertion(+)Qatorma-qator:
Updating 297cd7e..bba9aee— "main297cd7edanbba9aeega yangilanmoqda".Fast-forward— "oldinga o'tkazish". Yangi commit yaratilmadi.- Qolgani — qaysi fayllar o'zgargani, xuddi commit natijasidagidek.
2.3 Aslida nima bo'ldi?
git log --oneline --graph --all* bba9aee (HEAD -> main, fix/aloqa-manzil) Aloqa: manzilni qo'sh
* 297cd7e Menyu: shashlik narxini qo'sh
| * d6772a4 (feature/bron-forma) Bron: telefon maydonini qo'sh
| * 108e327 Bron: formani qo'sh
|/
* 1db8b60 Rasm: choy suratini qo'sh
* 56b3259 Menyu: somsa narxini qo'sh
...main endi bba9aee da — fix/aloqa-manzil bilan yonma-yon. Git hech narsani "birlashtirmadi". U shunchaki main ko'rsatkichini chiziq bo'ylab oldinga surdi. Oldingi darsda ko'rganimizdek, branch — 41 baytlik fayl. Fast-forward shu faylga yangi SHA yozishdan iborat.
gitGraph
commit id: "1db8b60"
commit id: "297cd7e shashlik"
branch fix/aloqa-manzil
commit id: "bba9aee manzil"
checkout main
merge fix/aloqa-manzilNimaga qarang: diagramma chizish qoidasi tufayli oxirida birlashish nuqtasi ko'rinadi. Haqiqiy tarixda esa yangi commit yo'q — git log --graph natijasidagi to'g'ri chiziq aynan shuni aytadi. main bba9aee ga yetib keldi, xolos.
Fast-forward faqat bitta holatda mumkin: joriy branch'ning oxirgi commiti qo'shilayotgan branch tarixida bor bo'lsa. Ya'ni joriy branch "orqada qolgan", lekin yo'ldan chiqmagan. Xuddi mashina bitta yo'lda old tomondagisiga yetib olgandek.
2.4 Ikkinchi marta merge
Xuddi shu buyruqni yana bir marta yozamiz:
git merge fix/aloqa-manzilAlready up to date."Allaqachon yangilangan" — qo'shadigan hech narsa yo'q. Xato emas.
Branch'ning ishi main da. Endi uni o'chirish xavfsiz — -d rad etmaydi:
git branch -d fix/aloqa-manzilDeleted branch fix/aloqa-manzil (was bba9aee).Tekshirib ko'ring: Fast-forward'dan keyin
git logda yangi commit paydo bo'ladimi?
Javob
Yo'q. Fast-forward hech qanday commit yaratmaydi — faqat main ko'rsatkichini mavjud commitga ko'chiradi. Tarixda o'sha-o'sha commitlar, faqat main yorlig'i boshqa joyda.
3. Uch tomonlama merge
3.1 Tarix ayrilgan bo'lsa
Endi forma. feature/bron-forma 1db8b60 dan ajralgan, main esa o'shandan beri ikki qadam yurdi: shashlik va manzil. Bu safar fast-forward mumkin emas. Buni --ff-only bayrog'i bilan tekshirib ko'ramiz — u "faqat fast-forward bo'lsa birlashtir, aks holda hech narsa qilma" degani:
git merge --ff-only feature/bron-formahint: 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.Tarjimasi: "Ayrilgan branch'larni fast-forward qilib bo'lmaydi, sizga yo git merge --no-ff, yo git rebase kerak. Fast-forward mumkin emas, to'xtatildi". Hech narsa o'zgarmadi. Git maslahat berayotgan ikkinchi yo'l — rebase — Rebase darsida. Hozir birinchi yo'l: haqiqiy birlashtirish.
3.2 Merge base — umumiy ajdod
Ikki chiziqni birlashtirish uchun Git avval ular qayerda ajralganini topadi. Bu nuqta merge base (umumiy ajdod) deyiladi. Uni so'rash mumkin:
git merge-base main feature/bron-forma1db8b6069b0c968277284b43cdf79a6d629a5515Bu — 1db8b60, choy surati commiti: oldingi darsning diagrammasidagi ayrilish nuqtasi. Git nega uni qidiradi? Chunki faqat ikki uchni solishtirish yetmaydi.
Misol. bron/index.html fayli main da bitta qatorli, feature/bron-forma da esa olti qatorli. Faqat shu ikkitasiga qarab, Git bilolmaydi: forma bir tomonda qo'shildimi yoki ikkinchi tomonda o'chirildimi? Umumiy ajdodga qaraydi: u yerda fayl bitta qatorli edi. Demak main faylga tegmagan, feature/bron-forma esa formani qo'shgan. Natijaga forma kiradi.
Shuning uchun nomi — uch tomonlama merge (three-way merge). Git uchta versiyani solishtiradi:
| Versiya | «Bahor»da | Nima beradi |
|---|---|---|
| Merge base | 1db8b60 |
Ajralishdan oldingi holat |
| Joriy branch uchi | main — bba9aee |
Bir tomonda nima o'zgargan |
| Qo'shilayotgan branch uchi | feature/bron-forma — d6772a4 |
Ikkinchi tomonda nima o'zgargan |
Har bir fayl bo'lagi uchun Git so'raydi: "kim o'zgartirdi?" Faqat bir tomon o'zgartirgan bo'lsa — o'sha o'zgarish olinadi. Hech kim tegmagan bo'lsa — o'z holicha qoladi. Ikkala tomon bir joyni turlicha o'zgartirgan bo'lsa — Git o'zi hal qilmaydi. Bu conflict (konflikt) — Git qarorni sizga qoldiradi. Uni keyingi darsda yechamiz.
3.3 Merge commit xabari
git merge feature/bron-formaBu safar Git sizdan xabar so'raydi: VS Code'da MERGE_MSG nomli tab ochiladi. Ichida tayyor xabar va izohlar bor. Biz uni muharrir o'rniga ekranga chiqarib ko'rdik:
Merge branch 'feature/bron-forma'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.Tarjimasi (izohlar): "Bu merge nega kerakligini tushuntiruvchi xabar kiriting. # bilan boshlangan qatorlar hisobga olinmaydi, bo'sh xabar commitni bekor qiladi". Birinchi qator — Git tayyorlagan xabar: Merge branch 'feature/bron-forma'. Odatda uni o'zgartirmay, tabni yopish kifoya. Muharrir ochilmasin desangiz — git merge --no-edit feature/bron-forma.
Tab yopilgach:
Merge made by the 'ort' strategy.
bron/index.html | 5 +++++
1 file changed, 5 insertions(+)"Merge 'ort' strategiyasi bilan qilindi". ort — Git 2.34 dan beri standart birlashtirish algoritmining nomi. Uni tanlash yoki sozlash hech qachon kerak bo'lmaydi.
3.4 Natija — ikki otali commit
git log --oneline --graph --all* fd7b1ae (HEAD -> main) Merge branch 'feature/bron-forma'
|\
| * d6772a4 (feature/bron-forma) Bron: telefon maydonini qo'sh
| * 108e327 Bron: formani qo'sh
* | bba9aee Aloqa: manzilni qo'sh
* | 297cd7e Menyu: shashlik narxini qo'sh
|/
* 1db8b60 Rasm: choy suratini qo'sh
* 56b3259 Menyu: somsa narxini qo'sh
...Yuqorida yangi commit — fd7b1ae. Undan ikki chiziq pastga tushadi (|\): biri main ning oldingi uchiga, biri forma branch'iga. Pastda esa |/ — ikki chiziq ajralgan joy.
gitGraph
commit id: "1db8b60"
branch feature/bron-forma
commit id: "108e327 forma"
commit id: "d6772a4 telefon"
checkout main
commit id: "297cd7e shashlik"
commit id: "bba9aee manzil"
merge feature/bron-forma id: "fd7b1ae merge"Nimaga qarang: merge commit ikkala chiziqning uchidan o'q oladi. Shuning uchun uning ikki otasi bor. Oddiy commitda ota bitta.
Buni isbotlaymiz. Git ichkaridan darsidagi git cat-file -p commit obyektini ochib ko'rsatadi:
git cat-file -p HEADtree 684db739e34f20839714c277b913dfbf8076e23c
parent bba9aee76021f03a510ed1a7a9c7080be9ed8315
parent d6772a4be7fbfc3abe118e9899f6dac0c8d1ed11
author Aziz Karimov <aziz@example.com> 1791952200 +0500
committer Aziz Karimov <aziz@example.com> 1791952200 +0500
Merge branch 'feature/bron-forma'Ikkita parent qatori! Birinchisi — merge paytida siz turgan branch (main) uchi. Ikkinchisi — qo'shilgan branch uchi. Tarixni o'qish darsidagi HEAD^ yozuvi aslida HEAD^1 — birinchi ota. Ikkinchisiga HEAD^2 bilan murojaat qilinadi:
git log --oneline -1 HEAD^1
git log --oneline -1 HEAD^2bba9aee Aloqa: manzilni qo'sh
d6772a4 (feature/bron-forma) Bron: telefon maydonini qo'sh3.5 Faqat asosiy chiziq: --first-parent
Merge commitli tarixda ba'zan faqat main ning o'z qadamlari kerak bo'ladi. --first-parent har merge commitda faqat birinchi otaga yuradi:
git log --oneline --first-parentfd7b1ae (HEAD -> main) Merge branch 'feature/bron-forma'
bba9aee Aloqa: manzilni qo'sh
297cd7e Menyu: shashlik narxini qo'sh
1db8b60 Rasm: choy suratini qo'sh
...Forma ichidagi ikki commit ko'rinmaydi — ular bitta "Merge branch" qatoriga yig'ilgan. Katta loyihalarda main tarixini shu tarzda o'qish qulay: har qator — bitta tugallangan ish.
Branch endi --merged ro'yxatida — uni o'chirsak bo'ladi:
git branch --merged
git branch -d feature/bron-forma feature/bron-forma
* main
Deleted branch feature/bron-forma (was d6772a4).Branch o'chdi, lekin uning ikki commiti tarixda qoladi — merge commitning ikkinchi otasi orqali. Branch nomi faqat ish davomida kerak edi.
Tekshirib ko'ring: Merge commitda nega aynan ikkita
parentbor? Birinchi va ikkinchi ota o'rnini nima belgilaydi?
Javob
Merge commit ikki tarixni birlashtiradi, shuning uchun ikkalasining uchiga bog'lanadi. Birinchi ota — merge paytida siz turgan branch uchi (bizda main). Ikkinchi ota — git merge ga nomi berilgan branch uchi. Agar feature/bron-forma da turib git merge main qilganimizda, tartib teskari bo'lardi.
4. --no-ff: har doim merge commit
4.1 Muammo
Fast-forward tarixni toza saqlaydi, lekin bitta narsani yo'qotadi. Aloqa sahifasiga yo'l ko'rsatkich qo'shish uchun ikki commitli branch ochamiz:
git switch -c feature/aloqa-xarita
echo '<h2>Bizni qanday topasiz</h2>' >> aloqa/index.html
git add aloqa/index.html
git commit -m "Aloqa: yo'l ko'rsatkich sarlavhasini qo'sh"
echo '<p>Metro: Bodomzor bekatidan 5 daqiqa</p>' >> aloqa/index.html
git add aloqa/index.html
git commit -m "Aloqa: metro bekatini qo'sh"
git switch mainSwitched to a new branch 'feature/aloqa-xarita'
[feature/aloqa-xarita 2c5510a] Aloqa: yo'l ko'rsatkich sarlavhasini qo'sh
1 file changed, 1 insertion(+)
[feature/aloqa-xarita 8da0793] Aloqa: metro bekatini qo'sh
1 file changed, 1 insertion(+)
Switched to branch 'main'main bu orada yurmadi, shuning uchun oddiy git merge fast-forward qiladi. Natijada ikki commit main chizig'iga tekis tushadi. Bir oydan keyin tarixga qarasangiz, "bu ikki commit bitta ishning qismlari edi" degan ma'lumot qolmaydi.
4.2 Yechim
--no-ff (no fast-forward) Git'ga aytadi: "fast-forward mumkin bo'lsa ham, merge commit yarat":
git merge --no-ff feature/aloqa-xarita
git log --oneline --graph -9Merge made by the 'ort' strategy.
aloqa/index.html | 2 ++
1 file changed, 2 insertions(+)
* c3673b8 (HEAD -> main) Merge branch 'feature/aloqa-xarita'
|\
| * 8da0793 (feature/aloqa-xarita) Aloqa: metro bekatini qo'sh
| * 2c5510a Aloqa: yo'l ko'rsatkich sarlavhasini qo'sh
|/
* fd7b1ae Merge branch 'feature/bron-forma'
|\
| * d6772a4 Bron: telefon maydonini qo'sh
| * 108e327 Bron: formani qo'sh
* | bba9aee Aloqa: manzilni qo'sh
* | 297cd7e Menyu: shashlik narxini qo'sh
|/
* 1db8b60 Rasm: choy suratini qo'sh(Bu yerda ham VS Code'da xabar tabi ochiladi — yopamiz.) Endi tarixda "cho'ntak" bor: ikki commit bitta merge ostida guruhlangan. Bu cho'ntakning pastki uchi to'g'ridan-to'g'ri oldingi merge'ga tutashadi — main o'rtada yurmagani shundan ko'rinadi.
gitGraph
commit id: "fd7b1ae merge"
branch feature/aloqa-xarita
commit id: "2c5510a sarlavha"
commit id: "8da0793 metro"
checkout main
merge feature/aloqa-xarita id: "c3673b8 merge"Nimaga qarang: main chizig'ida yangi commit yo'q edi, lekin merge commit baribir yaratildi. Endi git log --first-parent da bu ish bitta qator bo'lib ko'rinadi.
git branch -d feature/aloqa-xarita4.3 Qaysi biri yaxshi?
| Usul | Tarix | Qachon |
|---|---|---|
| Fast-forward | To'g'ri chiziq, merge commit yo'q | Bitta kichik commit, shaxsiy loyiha |
--no-ff |
Har ish — alohida cho'ntak | Bir necha commitli ish, jamoa loyihasi |
--ff-only |
Faqat to'g'ri chiziq, bo'lmasa to'xtaydi | "Tasodifan merge commit qilib qo'ymay" degan ehtiyot |
Yagona to'g'ri javob yo'q — jamoalar o'zi kelishadi. GitHub'dagi Pull Request tugmasi standart holatda --no-ff kabi ishlaydi: har PR — bitta merge commit. Buni Pull Request darsida ko'rasiz. --ff-only esa Ajralgan tarix darsida git pull bilan birga yana uchraydi.
Tekshirib ko'ring:
mainoldinga ketmagan paytdagit merge --no-ff feature/xvagit merge feature/xnatijasidamaindagi fayllar farq qiladimi?
Javob
Yo'q, fayllar bir xil. Ikkala holatda ham main feature/x dagi barcha o'zgarishlarni oladi. Farq faqat tarix shaklida: --no-ff qo'shimcha merge commit yaratadi va ish alohida cho'ntakda ko'rinadi.
5. Ko'p uchraydigan xatolar
5.1 Noto'g'ri yo'nalish
Eng ko'p xato — merge'ni teskari branch'da qilish. Aziz forma branch'ida turib git merge main yozdi va "nega main da forma yo'q?" deb hayron. Qoida: siz turgan branch o'zgaradi, nomi yozilgan branch — yo'q. main ga olib kelish uchun avval git switch main, keyin git merge feature/.... Merge'dan oldin git branch --show-current yoki promptdagi nomga qarang.
5.2 Branch nomida xato
git merge feature/menyumerge: feature/menyu - not something we can mergeTarjimasi: "feature/menyu — birlashtirsa bo'ladigan narsa emas". Bunday branch yo'q. Git "branch topilmadi" demaydi, chunki git merge ga commit SHA'si yoki tag ham berish mumkin — u shunchaki bu nomni hech narsaga bog'lay olmadi. Tuzatish: git branch bilan to'g'ri nomni tekshiring, Tab bilan to'ldiring.
5.3 Saqlanmagan o'zgarish
Rustam fix/aloqa-tel branch'ida aloqa sahifasiga telefon raqamini yozdi. Siz esa main da o'sha faylni o'zgartirib, commit qilmay turibsiz:
git status -s
git merge fix/aloqa-tel M aloqa/index.html
Updating c3673b8..076bc39
error: Your local changes to the following files would be overwritten by merge:
aloqa/index.html
Please commit your changes or stash them before you merge.
AbortingTarjimasi: "Quyidagi fayllardagi mahalliy o'zgarishlaringiz merge tufayli ustidan yozilib ketadi. Merge'dan oldin commit qiling yoki stash qiling. To'xtatildi". Branch nima darsidagi git switch xatosining egizagi. Git sizning saqlanmagan ishingizni himoya qildi — hech narsa o'zgarmadi.
Tuzatish: ishingizni commit qiling yoki kerak bo'lmasa git restore bilan qaytaring, keyin merge'ni takrorlang:
git restore aloqa/index.html
git merge fix/aloqa-telUpdating c3673b8..076bc39
Fast-forward
aloqa/index.html | 1 +
1 file changed, 1 insertion(+)Maslahat: Merge'dan oldingi odat —
git status. "working tree clean" bo'lmasa, merge qilmang.
5.4 Merge commit xabarini bo'sh qoldirish
VS Code'da MERGE_MSG tabidagi Merge branch ... qatorini ham o'chirib yopsangiz, Git merge commitni yaratmaydi:
error: Empty commit message.
Not committing merge; use 'git commit' to complete the merge.Tarjimasi: "xato: commit xabari bo'sh. Merge commit qilinmadi; merge'ni yakunlash uchun git commit ishlating". Lekin merge jarayoni to'xtab qolgan holatda turadi: git status "All conflicts fixed but you are still merging" deydi. Tuzatish: git commit yozing — muharrir yana ochiladi, bu safar xabarni qoldiring.
5.5 "Merge — branch'ni o'chiradi"
Yo'q. git merge qo'shilgan branch'ga tegmaydi — u joyida qoladi. O'chirish alohida qadam: git branch -d. Ko'p boshlovchilarda o'nlab eski branch to'planib qoladi. Odat: merge'dan keyin darhol -d.
6. Mashqlar
1-mashq (oson): Fast-forward yoki merge commit?
Har holatda git switch main va git merge feature/x dan keyin nima bo'ladi — fast-forward yoki merge commit?
feature/xmaindan ochilgan, unda 3 ta commit.mainda shu orada hech narsa bo'lmagan.feature/xda 1 ta commit. Shu oradamainga boshqa branch qo'shilgan.- 1-holat, lekin buyruq
git merge --no-ff feature/x. - 2-holat, lekin buyruq
git merge --ff-only feature/x.
Yechim
- Fast-forward —
maino'z joyida turibdi,feature/xundan oldinda. - Merge commit — ikkala tomonda yangi commit bor, tarix ayrilgan.
- Merge commit —
--no-fffast-forward'ni taqiqlaydi. - Hech narsa bo'lmaydi:
fatal: Not possible to fast-forward, aborting.Tarix ayrilgan,--ff-onlyesa faqat fast-forward'ga ruxsat beradi.
2-mashq (o'rta): Bo'sh joylarni to'ldiring
Bosh sahifaga Telegram kanal havolasi qo'shamiz. «Bahor» tarixini buzmaslik uchun mashqni sinov-git dagi yangi kichik repoda qiling. Ish tarixda alohida cho'ntak bo'lib qolsin:
cd ~/kurs/sinov-git
git init telegram
cd telegram
echo '<h1>Bahor</h1>' > index.html
git add index.html
git commit -m "Bosh sahifa: sahifa yarat"
git switch -c feature/telegram
echo '<a href="https://t.me/sizning_kanal">Telegram</a>' >> index.html
git add index.html
git commit -m "Bosh sahifa: Telegram havolasini qo'sh"
git switch
git merge feature/telegram
git branch feature/telegramIshora: merge siz turgan branch'ga qo'shiladi; cho'ntak — «--no-ff: har doim merge commit» bo'limi; o'chirish — Branch nima.
Yechim
git switch main
git merge --no-ff feature/telegram
git branch -d feature/telegram
git log --oneline --graph -4git merge --no-ff VS Code'da xabar tabini ochadi — yopasiz. -d xatosiz o'chiradi, chunki branch'ning ishi endi main da. Oxirgi buyruq natijasi:
* ec78e0c (HEAD -> main) Merge branch 'feature/telegram'
|\
| * 5114f19 Bosh sahifa: Telegram havolasini qo'sh
|/
* c8cc6d1 Bosh sahifa: sahifa yaratmain shu orada yurmagan bo'lsa ham, merge commit bor — --no-ff shuni ta'minladi.
3-mashq (qiyin): Otalarni toping
Tashlab yuboriladigan repoda shunday tarix yarating (har echo dan keyin git add . va git commit -m "<harf>"):
cd ~/kurs/sinov-git
git init mashq16
cd mashq16
echo A > a.txt # commit "A"
git switch -c x
echo B > b.txt # commit "B"
git switch main
echo C > c.txt # commit "C"
git merge x- Oxirgi buyruq fast-forward qiladimi yoki merge commit?
- Merge commitning birinchi va ikkinchi otasi qaysi commitlar?
git merge-base main xmerge'dan oldin nima qaytargan bo'lardi?
Ishora: tarix ayrilganmi — «Uch tomonlama merge» bo'limi; otalar tartibi — HEAD^1 va HEAD^2.
Yechim
Biz aynan shu buyruqlarni bajardik. Merge natijasi va tarix:
Merge made by the 'ort' strategy.
b.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 b.txt
* c23b13f (HEAD -> main) Merge branch 'x'
|\
| * 5471ce1 (x) B
* | 14e4c61 C
|/
* 33d8df9 A- Merge commit:
maindaC,xdaB— tarix ayrilgan. - Birinchi ota —
C(mainuchi, siz turgan branch), ikkinchi ota —B(xuchi). Tekshirish:git log --oneline -1 HEAD^2. Acommitining SHA'si — ikkala chiziq shu yerdan ajralgan.
create mode 100644 b.txt — yangi fayl main ga merge orqali keldi. SHA'lar sizda boshqacha bo'ladi.
4-mashq: Portfolio qadami — birinchi merge
Oldingi darsda portfolio'da feature/git-konikma branch'ini ochgan edingiz. Endi uni main ga qo'shamiz. Keyin yana bitta kichik ishni --no-ff bilan qilamiz.
~/kurs/portfoliodagit log --oneline --graph --allbilan holatni ko'ring.mainga o'tib,feature/git-konikmani birlashtiring. Fast-forward bo'ldimi?- Branch'ni
-dbilan o'chiring. feature/aloqa-telegrambranch'ini oching. Aloqa sahifasiga Telegram havolasi qo'shing:<a href="https://t.me/sizning_kanal">Telegram</a>(sizning_kanalo'rniga o'zingiznikini yozing). Commit:Aloqa: Telegram havolasini qo'sh.mainga--no-ffbilan qo'shing va branch'ni o'chiring.git log --oneline --graph --allbilan natijani ko'ring.
mashqlar repo: shu darsning 1–3-mashq javoblarini mashqlar/07/16-merge/javoblar.md ga yozing va commit qiling: 07/16: merge mashqlari javoblarini qo'sh.
Yechim
cd ~/kurs/portfolio
git log --oneline --graph --all
git switch main
git merge feature/git-konikma
git branch -d feature/git-konikma
git switch -c feature/aloqa-telegram
# VS Code'da sayt/aloqa/index.html ga havola qo'shing
git add sayt/aloqa/index.html
git commit -m "Aloqa: Telegram havolasini qo'sh"
git switch main
git merge --no-ff feature/aloqa-telegram
git branch -d feature/aloqa-telegram
git log --oneline --graph --allQisqa sinov portfolio'sidagi birinchi merge va oxirgi tarix:
Updating 086fe19..fc1e527
Fast-forward
sayt/haqimda/index.html | 1 +
1 file changed, 1 insertion(+)
* ba79bb9 (HEAD -> main) Merge branch 'feature/aloqa-telegram'
|\
| * af6f3e0 Aloqa: Telegram havolasini qo'sh
|/
* fc1e527 Haqimda: Git ko'nikmasini qo'sh
* 086fe19 Git: qator oxirlarini .gitattributes bilan tartibla
* 63190c1 Portfolio: 06-qism oxiridagi holatBirinchi merge — fast-forward: main shu orada yurmagan edi. Ikkinchisi — --no-ff tufayli cho'ntak. Sizda tarix uzunroq va SHA'lar boshqacha. Sayt hali GitHub'da yangilanmaydi — repo bog'lanmagan (Remote darsida bog'laymiz).
7. Real ishda
- Pull Request = merge. GitHub'dagi "Merge pull request" tugmasi aynan shu darsdagi ishni serverda bajaradi. U yerda uch usul bor: merge commit, squash va rebase. Ularni Pull Request darsida solishtiramiz.
- Kim merge qiladi? Jamoada
mainga odatda o'zingiz emas, tekshiruvdan keyin tizim qo'shadi. Lekin lokal merge baribir har kuni kerak:maindagi yangiliklarni o'z branch'ingizga olish uchun. --first-parentbilan hisobot. "Bu hafta nima chiqdi?" degan savolgagit log --first-parentjavob beradi — har qator bitta PR.- Intervyuda so'raladi: "Fast-forward va merge commit farqi?", "Merge commitning nechta otasi bor?" Bu darsdan keyin ikkalasiga ham misol bilan javob bera olasiz.
Xulosa
git merge <branch>shu branch'ning ishini siz turgan branch'ga qo'shadi.- Fast-forward — joriy branch orqada qolgan bo'lsa, ko'rsatkich shunchaki suriladi; yangi commit yo'q.
- Tarix ayrilgan bo'lsa — uch tomonlama merge: merge base va ikki uch solishtirilib, ikki otali merge commit yaratiladi.
HEAD^1— birinchi ota (siz turgan branch),HEAD^2— qo'shilgan branch;--first-parentfaqat asosiy chiziqni ko'rsatadi.--no-ffhar doim merge commit qiladi,--ff-onlyfaqat fast-forward'ga ruxsat beradi.- Merge'dan oldin —
git statustoza bo'lsin, keyin —git branch -d.
Keyingi dars: Conflictlarni yechish amaliyoti — ikki kishi bitta qatorni turlicha o'zgartirsa, Git nima deydi va buni qanday xotirjam hal qilish kerak.
Manbalar
- Pro Git kitobi: "Basic Branching and Merging" — git-scm.com/book
- Git hujjati: "git-merge", "git-merge-base" — git-scm.com/docs
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!