9-bo‘lim
Birlashtirish va konfliktlar
Fast-forward va uch tomonlama merge, konflikt nima uchun chiqadi va uni qanday to'g'ri hal qilish kerak.
Ushbu bo‘lim mundarijasi
Tarmoqda ish tugagach, uni asosiy tarmoqqa qo'shish kerak. Bu jarayon merge (birlashtirish) deb ataladi.
Oddiy birlashtirish #
# Qabul qiluvchi tarmoqqa o'tamiz
git switch main
# Tarmoqni birlashtiramiz
git merge feature/qidiruv
Updating c9d2e71..7d4e2f8
Fast-forward
manba/qidiruv.php | 1 +
manba/qidiruv-mantiq.php | 1 +
2 files changed, 2 insertions(+)
git merge X - "X ni joriy tarmoqqa qo'sh" degani.
Ya'ni avval maqsad tarmog'iga o'tish, keyin merge qilish kerak. Boshlovchilar ko'pincha buni teskari qiladi.
Fast-forward nima? #
Uch tomonlama merge #
Agar main da ham yangi kommitlar bo'lsa, Git merge kommit yaratadi:
git merge feature/savat
Merge made by the 'ort' strategy.
manba/savat.php | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
Git muharrirni ochib, xabar so'raydi:
Merge branch 'feature/savat' into main
Odatda standart xabar yetarli.
Merge turini boshqarish #
# Har doim merge kommit yaratish (fast-forward bo'lsa ham)
git merge --no-ff feature/savat
# Faqat fast-forward bo'lsa birlashtirish, aks holda to'xtash
git merge --ff-only feature/savat
# Barcha kommitlarni bitta kommitga jamlash
git merge --squash feature/savat
git commit -m "Savat imkoniyati qo'shildi"
--no-ff nima uchun foydali?Fast-forward da tarix chiziqli bo'ladi va "bu ish qaysi tarmoqda qilingani" ko'rinmaydi.
--no-ff bilan har bir imkoniyat tarixda alohida "pufak" bo'lib qoladi:
* 4b8e2a1 Merge branch 'feature/savat'
|\
| * 7d4e2f8 Savat mantiqi
| * 3a9c1b5 Savat sahifasi
|/
* c9d2e71 Kitoblar sahifasi
Ko'p jamoalar main ga merge qilishda har doim --no-ff ishlatadi.
--squash qachon kerak?Tarmoqda 15 ta kommit bor: "ishlamayapti", "yana urinish", "endi ishladi", "typo".
--squash ularning hammasini bitta toza kommitga aylantiradi.
main tarixi o'qilishi oson bo'ladi.
Kamchiligi: tarmoqning ichki tarixi yo'qoladi.
Konflikt #
Konflikt ikkala tarmoqda ham bir xil faylning bir xil satri o'zgartirilganda chiqadi.
git merge feature/dizayn
Auto-merging manba/index.php
CONFLICT (content): Merge conflict in manba/index.php
Automatic merge failed; fix conflicts and then commit the result.
Agar siz faylning boshini, hamkasbingiz oxirini o'zgartirgan bo'lsa - Git ikkalasini avtomatik birlashtiradi.
Konflikt faqat aynan bir xil satrlar o'zgarganda chiqadi. Bu boshlovchilar o'ylaganidan ancha kam uchraydi.
Konflikt belgilari #
Fayl ichi shunday ko'rinadi:
<?php
$sarlavha = 'Kutubxona';
<<<<<<< HEAD
echo '<h1 class="asosiy">' . $sarlavha . '</h1>';
=======
echo '<h1 id="sarlavha">' . $sarlavha . '</h1>';
>>>>>>> feature/dizayn
// Oxiri
| Belgi | Ma'nosi |
|---|---|
<<<<<<< HEAD | Joriy tarmoqdagi (sizning) versiya boshlanishi |
======= | Ajratuvchi |
>>>>>>> feature/dizayn | Kelayotgan tarmoq versiyasi oxiri |
Konfliktni hal qilish #
1-qadam. Faylni oching va belgilarni o'chirib, kerakli kodni qoldiring:
<?php
$sarlavha = 'Kutubxona';
echo '<h1 id="sarlavha" class="asosiy">' . $sarlavha . '</h1>';
// Oxiri
<<<<<<<, =======, >>>>>>> satrlari kodda qolib ketmasin.
Bu eng ko'p uchraydigan xato - sayt shundan keyin oq ekran ko'rsatadi. Kommitdan oldin qidirib chiqing:
git diff --check
grep -rn "<<<<<<<" .
2-qadam. Faylni sahnaga qo'ying:
git add manba/index.php
3-qadam. Merge ni yakunlang:
git commit
[main 9c2f5a8] Merge branch 'feature/dizayn'
Konflikt paytidagi holat #
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: manba/index.php
# Faqat konfliktli fayllarni ko'rish
git diff --name-only --diff-filter=U
Merge ni bekor qilish #
git merge --abort
Hammasi merge boshlanishidan oldingi holatga qaytadi.
Konflikt ko'rganda ko'p boshlovchi qo'rqib ketadi. Aslida:
git merge --aborthar doim orqaga qaytaradi- Hech narsa yo'qolmaydi
- Konfliktni istalgancha marta qayta boshlash mumkin
Konflikt - xato emas, normal ish jarayoni.
Bir tomonni tanlash #
Ba'zan butun faylning bitta versiyasi kerak:
# O'zimizning versiyani olish
git checkout --ours manba/index.php
# Kelayotgan versiyani olish
git checkout --theirs manba/index.php
git add manba/index.php
ours va theirs chalkashtiradimerge paytida:
- ours - siz turgan tarmoq (
main) - theirs - birlashtirilayotgan tarmoq (
feature)
rebase paytida esa teskari bo'ladi! Bu Git ning eng chalkash joyi.
Shubhalansangiz - faylni ochib o'z ko'zingiz bilan ko'ring.
Uch tomonni birga ko'rish #
git config --global merge.conflictstyle diff3
Endi konflikt shunday ko'rinadi:
<<<<<<< HEAD
echo '<h1 class="asosiy">' . $sarlavha . '</h1>';
||||||| umumiy ota
echo $sarlavha;
=======
echo '<h1 id="sarlavha">' . $sarlavha . '</h1>';
>>>>>>> feature/dizayn
O'rtadagi qism - asl holat. Uni ko'rish har bir tomon nimani o'zgartirganini tushunishga juda yordam beradi.
Masalan: yuqorida ikkala tomon ham echo $sarlavha; ni HTML bilan
o'ragan - faqat atributlar boshqacha. Yechim aniq: ikkalasini birlashtirish.
Vizual vosita #
git mergetool
Sozlash:
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
git config --global mergetool.keepBackup false
Konfliktdan qochish #
- Kichik va tez-tez kommit qiling - kam kod, kam konflikt.
- Tarmoqni tez-tez yangilang:
git switch feature/savat git merge mainHar kuni shunday qiling - konflikt kichik bo'ladi.
- Tarmoqni uzoq ushlab turmang - bir haftadan oshmasin.
- Jamoada gaplashing - kim qaysi faylda ishlayotganini biling.
- Formatlash qoidalarini kelishib oling -
.editorconfigva avtomatik formatlovchi konfliktlarning yarmini yo'q qiladi.
Amaliy misol #
# Ikkita tarmoq bir xil faylni o'zgartiradi
git switch -c tarmoq-a
echo "A versiyasi" > matn.txt
git commit -am "A qo'shildi"
git switch main
git switch -c tarmoq-b
echo "B versiyasi" > matn.txt
git commit -am "B qo'shildi"
git switch main
git merge tarmoq-a # muvaffaqiyatli
git merge tarmoq-b # KONFLIKT
CONFLICT (add/add): Merge conflict in matn.txt
cat matn.txt
<<<<<<< HEAD
A versiyasi
=======
B versiyasi
>>>>>>> tarmoq-b
echo "A va B versiyalari" > matn.txt
git add matn.txt
git commit -m "Merge: ikkala versiya birlashtirildi"
git log --oneline --graph
* 5f8a2c1 Merge: ikkala versiya birlashtirildi
|\
| * 3b7e9d4 B qo'shildi
* | 8c1f5a2 A qo'shildi
|/
* c9d2e71 Boshlang'ich holat
maindamatn.txtyarating va kommit qiling.tarmoq-ayarating, faylni o'zgartiring, kommit qiling.mainga qayting,tarmoq-byarating, shu satrni boshqacha o'zgartiring va kommit qiling.mainga qayting vatarmoq-ani merge qiling - fast-forward bo'lishini ko'ring.tarmoq-bni merge qiling - konfliktni oling.git statusbilan holatni ko'ring.git merge --abortbilan bekor qiling, keyin qaytadan boshlang.- Konfliktni qo'lda hal qiling va kommit qiling.
merge.conflictstyle diff3ni yoqing va farqni ko'ring.--no-ffva--squashvariantlarini sinab ko'ring.
Xulosa #
git merge X- X ni joriy tarmoqqa qo'shadi.- Fast-forward - qabul qiluvchi tarmoqda yangi kommit bo'lmaganda.
- Merge kommit - ikkita otasi bo'lgan yagona kommit turi.
--no-ffhar doim merge kommit yaratadi, tarixda tarmoq ko'rinadi.--squashbarcha kommitlarni bittaga jamlaydi.- Konflikt faqat bir xil satrlar o'zgarganda chiqadi.
- Konflikt belgilarini (
<<<<<<<,=======,>>>>>>>) albatta o'chiring. git merge --aborthar doim orqaga qaytaradi.merge.conflictstyle diff3asl holatni ham ko'rsatadi - uni yoqing.- Tez-tez merge qilish konfliktlarni kichik va oson qiladi.
Keyingi bo'limda masofaviy repozitoriylar bilan ishlashni boshlaymiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.