Merge Conflict — nima uchun chiqadi, qanday hal qilinadi

~20 daq · Git · Branch va Merge

Muammodan boshlaylik

git merge feature/chegirma
Auto-merging src/narx.js
CONFLICT (content): Merge conflict in src/narx.js
Automatic merge failed; fix conflicts and then commit the result.

Qizil yozuv, "CONFLICT", "failed". Ko'p yangi boshlovchilar shu yerda vahimaga tushadi: nimadir buzildimi? Kod yo'qoldimi?

Hech narsa buzilmadi va yo'qolmadi. Git shunchaki aytyapti: "Ikki kishi bitta joyni turlicha o'zgartirgan. Qaysi biri to'g'ri — men bilmayman. Siz hal qiling." Conflict — oddiy, kundalik holat. Bu darsda uni xotirjam hal qilishni o'rganamiz.


Conflict qachon chiqadi

15-darsdagi jadval — oxirgi qatori:

Asos:           narx = 100
main:           narx = 90      (Otabek: chegirma)
feature:        narx = 120     (Malika: narx oshirildi)

Bitta qator, ikki xil o'zgarish. Git uchun ikkalasi ham bir xil "to'g'ri" — u qaror qila olmaydi.

Conflict sabablari:

  • Bir xil qator(lar) ikkala branch da turlicha o'zgartirilgan
  • Bir branch faylni o'zgartirgan, ikkinchisi — o'chirgan
  • Ikkala branch da bir xil nomli yangi fayl turli mazmun bilan

Turli qatorlar, hatto bitta faylda ham — conflict emas, avtomatik birlashadi.


Conflict holatini ko'rish

git status
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   src/narx.js

Changes to be committed:
        modified:   src/savat.js
  • savat.js — avtomatik birlashtirilgan, staging da tayyor
  • narx.js — both modified: qo'lda hal qilish kerak

Conflict belgilari

src/narx.js ni oching:

export function narxHisobla(mahsulot) {
<<<<<<< HEAD
  const chegirma = mahsulot.narx * 0.10;
  return mahsulot.narx - chegirma;
=======
  const soliq = mahsulot.narx * 0.12;
  return mahsulot.narx + soliq;
>>>>>>> feature/chegirma
}
Belgi Ma'nosi
<<<<<<< HEAD Sizning (joriy branch — main) versiyangiz boshlanishi
======= Ajratuvchi
>>>>>>> feature/chegirma Qo'shilayotgan branch versiyasi tugashi

Conflict dan tashqaridagi hamma narsa — allaqachon to'g'ri birlashtirilgan.


Hal qilish — 4 qadam

1. Qaror qabul qiling

Uchta variant:

  • Biznikini qoldirish (HEAD)
  • Ularnikini qoldirish (feature)
  • Birlashtirish — ko'pincha to'g'ri javob

Bu yerda — ikkalasi ham kerak: chegirma ham, soliq ham.

2. Faylni tahrirlang

Belgilarni olib tashlab, yakuniy kodni yozing:

export function narxHisobla(mahsulot) {
  const chegirma = mahsulot.narx * 0.10;
  const narxChegirmabilan = mahsulot.narx - chegirma;
  const soliq = narxChegirmabilan * 0.12;
  return narxChegirmabilan + soliq;
}

[!WARNING] Barcha <<<<<<<, =======, >>>>>>> qatorlarini o'chirganingizga ishonch hosil qiling. Ular qolib ketsa — kod buziladi, va bu tez-tez uchraydigan xato. Tekshirish: grep -rn "<<<<<<<\|>>>>>>>" src/

3. Hal qilinganini belgilang

git add src/narx.js

Conflict da git add — "bu fayl hal qilindi" degani.

4. Merge ni yakunlang

git status                  # hamma narsa staged, conflict qolmadimi?
npm test                    # kod ishlayaptimi? — juda muhim!
git commit                  # merge commit (xabar tayyor bo'ladi)

Yoki git merge --continue.


VS Code da conflict

VS Code conflict larni rangli bloklar bilan ko'rsatadi va har birining tepasida tugmalar:

Accept Current Change | Accept Incoming Change | Accept Both Changes | Compare Changes
  • Current — HEAD (sizniki)
  • Incoming — qo'shilayotgan branch
  • Both — ikkalasi ketma-ket (keyin qo'lda tuzatish kerak bo'lishi mumkin)

Murakkab conflict lar uchun — Merge Editor ("Resolve in Merge Editor" tugmasi): uch panel — sizniki, ularniki va natija.

[!TIP] "Accept Both" — ko'pincha birinchi qadam, oxirgi emas. Yuqoridagi misolda ikkalasini qabul qilish ikki return ni beradi — kod noto'g'ri. Har doim natijani o'qing va mantiqan to'g'riligini tekshiring.


Butun faylni bitta tomondan olish

Ba'zan qaror oddiy — butun fayl uchun bitta tomon:

git checkout --ours src/narx.js       # HEAD versiyasi
git checkout --theirs src/narx.js     # qo'shilayotgan branch versiyasi
git add src/narx.js

package-lock.json kabi avtomatik yaratiladigan fayllarda conflict bo'lsa — qo'lda tahrirlamang:

git checkout --theirs package-lock.json
npm install                           # qayta yaratish
git add package-lock.json

Qo'rqsangiz — bekor qiling

Conflict juda murakkab, nima qilayotganingizni bilmaysiz:

git merge --abort

Hammasi merge dan oldingi holatga qaytadi. Hech narsa yo'qolmaydi. Hamkasbingiz bilan gaplashing, keyin qayta urinib ko'ring.


Conflict larni kamaytirish

Conflict larni butunlay yo'q qilib bo'lmaydi, lekin kamaytirish mumkin:

  1. Kichik, qisqa umrli branch lar — 2 kunlik branch da conflict kam, 2 haftalikda — ko'p
  2. main ni tez-tez feature ga qo'shing (git merge main yoki rebase) — conflict lar kichik bo'lganda hal qilinadi
  3. Kichik commit lar — har bir conflict tushunarliroq
  4. Formatlash vositasi (Prettier, ESLint) — butun jamoada bir xil. Aks holda biri bo'shliqlarni, ikkinchisi tablarni ishlatadi va har bir qator conflict ga aylanadi
  5. Muloqot — "men narx.js ni refaktoring qilyapman" degan bitta xabar soatlab ishni tejaydi

Bir xil conflict ni qayta hal qilmaslik

git config --global rerere.enabled true

rerere ("reuse recorded resolution") — Git siz conflict ni qanday hal qilganingizni eslab qoladi va xuddi shu conflict qayta chiqsa, o'zi qo'llaydi. Uzoq yashaydigan branch lar va rebase da foydali.


Nima uchun shunday?

Nima uchun Git conflict ni o'zi hal qilmaydi — masalan, "eng yangisini" olib?

Chunki conflict — texnik emas, mantiqiy muammo. Yuqoridagi misolda "eng yangi" versiyani olish — chegirma yoki soliqdan birini yo'qotish edi; to'g'ri javob esa — ikkalasini birlashtirish, buni faqat biznes mantiqni tushungan odam biladi. Agar Git taxmin qilsa, u ba'zan to'g'ri topardi, ba'zan esa jimgina xato kiritardi — va bunday xatolar eng xavflisi: kod kompilyatsiya bo'ladi, lekin noto'g'ri ishlaydi. Git ning falsafasi: aniq bo'lganini avtomatik qil, noaniqni odamga ko'rsat. Conflict — Git ning "men bu yerda xato qilishim mumkin, tekshiring" degan halol ogohlantirishi.


Xulosa

Eslab qoling:

  • Conflict — bir xil qatorni ikki tomon turlicha o'zgartirgan; normal holat
  • git status → "both modified" — qo'lda hal qilinadigan fayllar
  • <<<<<<< HEAD (sizniki) / ======= / >>>>>>> branch (ularniki)
  • Hal qilish: tahrirlash → belgilarni o'chirish → git add → test → git commit
  • VS Code: Accept Current / Incoming / Both; Merge Editor
  • --ours / --theirs — butun fayl uchun bitta tomon; lock fayllar — qayta yaratish
  • git merge --abort — xavfsiz bekor qilish
  • Kamaytirish: kichik branch lar, main ni tez-tez olish, formatter, muloqot, rerere

Keyingi dars

17-dars: git rebase — nima, merge dan farqi, qachon ishlatiladi