IlmHamroh
JavaScript Full-stack/7-qism. Git va GitHub asoslari5/36-dars25 daqiqa
Mundarija (43)

Yaxshi commit: atomar commit, git add -p va commit xabarini yozish

Qisqacha: Yaxshi commit — bitta mantiqiy o'zgarish (atomar commit) va uni aniq aytadigan xabar. Xabarning birinchi qatori 50 belgigacha, buyruq maylida ("Menyu: manti narxini qo'sh"), keyin bo'sh qator va kerak bo'lsa "nega" degan savolga javob beradigan tana. Bitta faylda ikki xil o'zgarish bo'lsa, git add -p ularni alohida commitlarga bo'lishga yordam beradi. Faylni o'chirish va nomini o'zgartirish ham commit: git rm va git mv.

Bu darsda

  • Atomar commit nima ekanini va o'zgarishlarni qanday bo'laklarga bo'lishni tushuntirasiz.
  • git add -p bilan bitta fayldagi ikki o'zgarishni ikki commitga ajratasiz.
  • 50/72 qoidasi va buyruq mayli bo'yicha commit xabari yozasiz, --verbose bilan nima ketayotganini ko'rasiz.
  • git rm va git mv oddiy rm va mv dan nimasi bilan farq qilishini bilasiz.
  • Portfolio'dagi eski nusxa faylni to'g'ri yo'l bilan o'chirasiz.

Oldin bilishingiz kerak: Birinchi repo: init, status, add, commit, Uch hudud.

1. Nega bu kerak?

Oldingi darsda birinchi commitlarni qildik. Commit qilishni endi bilasiz. Bugungi savol boshqa: qanday commit yaxshi?

Avval yomon tarixni ko'raylik. Sardor stajyorlikning birinchi haftasida tashlab yuboriladigan sinov repoda shunday ishladi. git log --oneline:

text
a83aac3 (HEAD -> main) oxirgisi
3531488 yana tuzatdim
591f1df asdf
a6b79b4 fix
2577470 o'zgarishlar
a00d787 boshlanish

Oltita commit bor, lekin ular hech narsa demaydi. ((HEAD -> main) — "siz shu yerdasiz" belgisi, Birinchi repo darsidan tanish.) Bir oydan keyin sayt buzilsa, qaysi commit aybdor? "fix" nimani tuzatgan? "asdf" ichida nima bor? Har birini ochib, qatorma-qator o'qishga to'g'ri keladi.

Versiya nazorati darsida tarixni "loyiha kundaligi" dedik. Kundalik faqat tushunarli yozilsa foyda beradi. Tarixni kim o'qiydi?

  • Siz o'zingiz, uch oydan keyin — "bu qatorni nega o'zgartirgan edim?"
  • Hamkasbingiz — kodni tekshirishdan (review) oldin.
  • Git'ning o'zi — keyinroq o'rganadigan buyruqlar bitta commitni butunligicha bekor qila oladi yoki boshqa joyga ko'chira oladi. Commit ichida ikki xil ish aralashgan bo'lsa, yaxshisini ham yomoni bilan birga bekor qilasiz.

HTML kod uslubi darsida "formatlashni mazmun o'zgarishlarisiz, alohida qiling" degan edik va "Git'da bu yanada muhim" deb va'da bergan edik. Bu qoidaning nomi — atomar commit.

2. Atomar commit

2.1 Bitta commit — bitta mantiqiy o'zgarish

Atomar commit (atomic commit) — bitta tugallangan, mantiqiy o'zgarishni o'z ichiga olgan commit. "Atom" so'zi "bo'linmaydigan" degan ma'noda: uni yana kichikroq, alohida ma'noga ega qismlarga bo'lib bo'lmaydi. Undan narsa olib tashlasangiz ham ish chala qoladi.

Choyxonadagi buyurtmani tasavvur qiling. Ofitsiant har stolning buyurtmasini alohida qog'ozga yozadi. Oshpaz bitta qog'ozga qarab bitta stolga ovqat tayyorlaydi. Agar uch stolning buyurtmasi bitta qog'ozga aralash yozilsa, bittasi bekor bo'lganda qaysi qatorni o'chirishni hech kim bilmaydi. Commit ham shunday: bitta commit — bitta stolning buyurtmasi.

Qanday bilish mumkin? Commitni bitta gap bilan tasvirlab ko'ring. Gapda "va" so'zi kerak bo'lib qolsa ("menyuga manti qo'shdim va bron sahifasiga telefon yozdim"), demak bu ikki commit.

2.2 Qanchalik kichik?

Atomar — "iloji boricha kichik" degani emas. O'lchov — mantiq, fayl soni emas:

Holat Commitlar soni
Menyuga manti qo'shish va bronga telefon yozish 2 — ikki mustaqil ish
CSS faylning nomini o'zgartirish va HTML'dagi havolani yangilash 1 — alohida qilsangiz, oradagi commitda sayt buziladi
Butun loyihani Prettier bilan formatlash 1 — faqat formatlash, mazmunsiz
Bitta jumladagi uchta imlo xatosini tuzatish 1 — bitta ish

Ikkinchi qatorga e'tibor bering. Fayl nomi o'zgarib, havola eski nomda qolsa, sayt stilsiz ochiladi. Bunday "yarim ish" commitda saqlanmasin. Qoida: har bir commitdan keyin loyiha ishlaydigan holatda bo'lishi kerak.

Tekshirib ko'ring: Aziz bir commitda uchta ish qildi: logotipni almashtirdi, footer'dagi yilni 2026 ga to'g'riladi, hamma HTML fayllarni Prettier bilan formatladi. Nechta commit bo'lishi kerak edi?

Javob

Uchta. Uchala ish bir-biriga bog'liq emas — har birini alohida bekor qilish yoki tekshirish mumkin bo'lishi kerak. Ayniqsa formatlash: u yuzlab qatorni o'zgartiradi va uning ichida logotip yoki yil o'zgarishi ko'rinmay qoladi.

3. Aralash o'zgarishlarni ajratish

3.1 Jasur akaning uchta topshirig'i

«Bahor» reposiga qaytamiz. Oldingi darsdagi 2-mashqni bajargan bo'lsangiz, tarix shunday:

text
07b061d (HEAD -> main) Menyu: lag'mon narxini qo'sh
bd98d1b Bron: rahmat sahifasini qo'sh
b09fa2a Aloqa: sahifa yarat
9084599 Bosh sahifa: aloqa havolasini qo'sh
f4238e7 Menyu: osh narxini qo'sh
dab5bff Bahor: sayt tuzilmasini yarat

Jasur aka telefonda uchta ish aytdi:

  1. Menyu sarlavhasida choyxona nomi bo'lsin: "Bahor menyusi".
  2. Menyuga manti qo'shilsin — 30 000 so'm.
  3. Bron sahifasida telefon raqami bo'lsin.

Aziz uchalasini ketma-ket, commit qilmasdan bajardi. Sarlavhani VS Code'da o'zgartirdi, qolgan ikkitasini terminalda qo'shdi:

bash
echo "<p>Manti — 30 000 so'm</p>" >> menyu/index.html
echo '<p>Telefon: +998 90 000 00 00</p>' >> bron/index.html
cat menyu/index.html
text
<h1>Bahor menyusi</h1>
<p>Osh — 35 000 so'm</p>
<p>Lag'mon — 28 000 so'm</p>
<p>Manti — 30 000 so'm</p>

Endi ish stolida uch ish aralash turibdi:

bash
git status -s
text
 M bron/index.html
 M menyu/index.html

Bu tabiiy holat — muhimi, commit qilayotganda ularni ajrata olish. Staging area aynan shuning uchun bor (Uch hudud).

Rejamiz — uchta commit:

flowchart LR
  W["Ish stoli:<br/>3 ta o'zgarish"] --> A["git add bron/..."]
  W --> B["git add -p<br/>(manti)"]
  W --> C["git add<br/>(sarlavha)"]
  A --> C1["1-commit:<br/>telefon"]
  B --> C2["2-commit:<br/>manti"]
  C --> C3["3-commit:<br/>sarlavha"]

Nimaga qarang: chapda bitta aralash ish stoli, o'ngda uchta commit. Telefon alohida faylda — u butun fayl bilan ajraladi. Manti va sarlavha bitta faylda — ularni fayl ichida bo'lish kerak.

3.2 Fayl bo'yicha ajratish

Telefon raqami boshqa faylda. Uni ajratish uchun yangi narsa kerak emas — faqat shu faylni qo'shamiz:

bash
git add bron/index.html
git status -s
text
warning: in the working copy of 'bron/index.html', LF will be replaced by CRLF the next time Git touches it
M  bron/index.html
 M menyu/index.html

Birinchi qator — tanish CRLF ogohlantirishi, xato emas. Bron qutida (M chap ustunda), menyu stolda (M o'ng ustunda). Commit:

bash
git commit -m "Bron: telefon raqamini qo'sh"
text
[main e50f485] Bron: telefon raqamini qo'sh
 1 file changed, 1 insertion(+)

Birinchi commit tayyor. Xabar oldingi darsdagi shaklda: soha, ikki nuqta va buyruq shaklidagi fe'l. Nega aynan shunday — «Commit xabarini yozish» bo'limida.

4. git add -p — fayl ichidan tanlash

4.1 Muammo

menyu/index.html da ikki mustaqil o'zgarish bor: sarlavha va manti. git add menyu/index.html ikkalasini birga qo'shadi. Bizga esa faqat manti kerak.

git add -p (--patch, "yamoq") — faylning o'zgarishlarini bo'lak-bo'lak ko'rsatadi va har biri uchun "qutiga solaymi?" deb so'raydi. Git bunday bo'lakni hunk deydi — bir-biriga yaqin o'zgargan qatorlar guruhi.

4.2 Birinchi seans

bash
git add -p menyu/index.html

Git birinchi bo'lakni ko'rsatadi va savol beradi. Quyida butun seans — ? belgisidan keyingi harf biz yozgan javob (har biridan keyin Enter bosiladi):

text
warning: in the working copy of 'menyu/index.html', LF will be replaced by CRLF the next time Git touches it
diff --git a/menyu/index.html b/menyu/index.html
index 8eecc12..e4f0bdb 100644
--- a/menyu/index.html
+++ b/menyu/index.html
@@ -1,3 +1,4 @@
-<h1>Menyu</h1>
+<h1>Bahor menyusi</h1>
 <p>Osh — 35 000 so'm</p>
 <p>Lag'mon — 28 000 so'm</p>
+<p>Manti — 30 000 so'm</p>
(1/1) Stage this hunk [y,n,q,a,d,s,e,p,P,?]? s
Split into 2 hunks.
@@ -1,3 +1,3 @@
-<h1>Menyu</h1>
+<h1>Bahor menyusi</h1>
 <p>Osh — 35 000 so'm</p>
 <p>Lag'mon — 28 000 so'm</p>
(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? n
@@ -2,2 +2,3 @@
 <p>Osh — 35 000 so'm</p>
 <p>Lag'mon — 28 000 so'm</p>
+<p>Manti — 30 000 so'm</p>
(2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,P,?]? y

Ko'p narsa bir ekranda — keling, sekin ko'ramiz.

4.3 Bo'lakni o'qish

Bo'lak — o'zgarishning "farq" ko'rinishi:

  • - bilan boshlangan qator — olib tashlangan (eski versiyada bor edi).
  • + bilan boshlangan qator — qo'shilgan (yangi versiyada bor).
  • Bo'sh joy bilan boshlangan qator — o'zgarmagan, faqat "qayerda ekanini" ko'rsatish uchun.

Sarlavhani almashtirish Git uchun ikki amal: eski qatorni olib tashlash va yangisini qo'shish. diff --git, index, @@ -1,3 +1,4 @@ kabi sarlavha qatorlarini O'zgarishlarni ko'rish darsida to'liq o'qiymiz.

4.4 Javoblar

Git birinchi bo'lakda ikkala o'zgarishni birga ko'rsatdi — ular yonma-yon, orasida atigi ikki qator. Shuning uchun s (split — "bo'l") yozdik. Git Split into 2 hunks. — "2 bo'lakka bo'lindi" dedi. Keyin:

  • 1/2 — sarlavha. Hozir kerak emas: n (no).
  • 2/2 — manti. Kerak: y (yes).

Eng ko'p ishlatiladigan javoblar:

Harf Ma'nosi
y Shu bo'lakni qutiga sol
n Solma, keyingisiga o't
s Bo'lakni kichikroqlarga bo'l
q Chiq, qolganlarini solma

Yana bir nechtasi bor: a — shu va keyingi hamma bo'laklarni sol, d — hech birini solma, e — bo'lakni qo'lda tahrirlash. Adashib qolsangiz, ? yozing — Git har bir harfni tushuntiradi.

s har doim ham ishlamaydi: ikki o'zgarish orasida o'zgarmagan qator bo'lmasa, Git ularni bo'la olmaydi. Unda e (qo'lda tahrirlash) qoladi — bu tajriba bilan keladigan usul.

4.5 Natija

bash
git status -s
text
MM menyu/index.html

Ikki M — tanishmi? Uch hudud darsida "bitta fayl — ikki holatda" ko'rgan edik. Chap M — qutida o'zgarish bor (manti), o'ng M — stolda yana o'zgarish qoldi (sarlavha). Qutidagi versiyani tekshiramiz:

bash
git show :menyu/index.html
text
<h1>Menyu</h1>
<p>Osh — 35 000 so'm</p>
<p>Lag'mon — 28 000 so'm</p>
<p>Manti — 30 000 so'm</p>

Aynan kerakli holat: manti bor, sarlavha esa eski. Commit:

bash
git commit -m "Menyu: manti narxini qo'sh"
git status -s
text
[main 285ac84] Menyu: manti narxini qo'sh
 1 file changed, 1 insertion(+)
 M menyu/index.html

Sarlavha o'zgarishi stolda kutib turibdi. Uni keyingi bo'limda boshqacha — muharrirda — commit qilamiz.

Tekshirib ko'ring: git add -p seansida hamma bo'lakka n javob bersangiz, nima bo'ladi?

Javob

Qutiga hech narsa tushmaydi. git status -s avvalgidek M ko'rsatadi, fayl esa o'zgarmaydi. git add -p faylga tegmaydi — u faqat qutiga nima solishni tanlaydi. Shuning uchun uni qo'rqmasdan sinab ko'rish mumkin.

5. Commit xabarini yozish

5.1 Xabarning tuzilishi

Commit xabari ikki qismdan iborat:

text
Menyu: sarlavhaga choyxona nomini qo'sh

Mehmonlar menyu sahifasini ko'pincha Google'dan to'g'ridan-to'g'ri
ochadi. Oddiy "Menyu" sarlavhasidan qaysi joy ekani bilinmasdi.
  • Sarlavha (subject) — birinchi qator. Qisqa: nima qilindi.
  • Bo'sh qator — majburiy ajratgich.
  • Tana (body) — ixtiyoriy. Nega qilindi, qanday muammo hal bo'ldi.

Git birinchi bo'sh qatorgacha bo'lgan matnni sarlavha deb hisoblaydi. git log --oneline, GitHub sahifalari, VS Code — hammasi aynan sarlavhani ko'rsatadi. Shuning uchun u qisqa va o'zi yetarli bo'lsin.

5.2 50/72 qoidasi

50/72 qoidasi — sarlavha 50 belgigacha, tana qatorlari esa 72 belgidan oshmasin.

  • 50 — Git'ning rasmiy hujjati ham shuni tavsiya qiladi: 50 belgidan oshmaydigan qisqa birinchi qator, keyin bo'sh qator va batafsil tavsif. Qisqa sarlavha --oneline kabi qisqa ro'yxatlarda to'liq sig'adi.
  • 72 — tana qatorlari. Git tanani o'zi qatorlarga bo'lmaydi. git log uni 4 bo'sh joy surib chiqaradi, shuning uchun 72 belgili qator oddiy 80 belgili terminalga sig'adi.

Bu qat'iy qonun emas. Lekin 50 dan oshsa, "bu commit ikki ish qilmayaptimi?" deb o'ylab ko'ring. Uzun sarlavha ko'pincha atomar bo'lmagan commitning belgisi.

5.3 Buyruq mayli

Git hujjati o'zgarishni buyruq maylida (imperative mood) tasvirlashni so'raydi: go'yo kodga buyruq beryapsiz. Inglizcha loyihalarda:

  • Add manti to menu — "Menyuga manti qo'sh"
  • Added manti to menu — "qo'shdim" (o'tgan zamon)
  • Adding manti — "qo'shyapman"

Nega aynan buyruq? Commit — kodga qo'llanadigan o'zgarish. Sarlavhani shu gapga qo'yib tekshiring: "Bu commit qo'llansa, u ... ". "Bu commit qo'llansa, u menyuga manti qo'shadi" — mantiqli. Git'ning o'zi ham shunday yozadi: keyinroq o'rganadigan buyruqlar avtomatik Merge branch ..., Revert ... kabi xabarlar yaratadi.

Kursimizdagi repolarda xabarlar o'zbekcha. Kelishuv shunday:

text
Soha: buyruq maylidagi qisqa gap

Soha — o'zgarish qayerda: Menyu, Bron, CSS, Bosh sahifa. Undan keyin fe'l buyruq maylida: qo'sh, tuzat, o'chir, ko'chir, yangila. Birinchi repo darsidan beri xabarlarimiz shunday edi — endi nega aynan shunday ekanini bilasiz. Keng tarqalgan xatolar:

Shunday emas Shunday Nega
osh narxi Menyu: osh narxini qo'sh Soha ham, fe'l ham yo'q
Menyu: osh narxi qo'shildi Menyu: osh narxini qo'sh Fe'l o'tgan zamonda
aloqa sahifasi Aloqa: sahifa yarat Nima qilingani noma'lum

Bu kelishuvning mashinalar o'qiy oladigan kengaytmasini (feat:, fix:) Conventional Commits darsida ko'rasiz.

5.4 Tana: "nima" emas, "nega"

"Nima o'zgardi" — Git o'zi ko'rsatadi: qaysi qator qo'shildi, qaysisi o'chdi. Tanaga Git bilmaydigan narsani yozing:

  • Nega? "Mehmonlar sahifani Google'dan ochadi, qaysi joy ekani bilinmasdi."
  • Qanday muammo? "Telefonda narxlar ikki qatorga bo'linib ketardi."
  • Nimaga e'tibor berish kerak? "Eski havolalar ham ishlashi uchun eski faylni qoldirdim."

Har commitga tana shart emas: "Menyu: manti narxini qo'sh" — o'zi yetarli. Tana sababi ko'rinmaydigan o'zgarishlar uchun.

Tekshirib ko'ring: Qaysi sarlavhalar kurs kelishuviga mos? a) Menyu: narxlarni yangila b) menyu o'zgartirildi c) Bron: formani tuzatdim va CSS'ni formatladim

Javob

Faqat a). b) da soha yo'q va fe'l o'tgan zamonda ("o'zgartirildi"). Qaysi o'zgarish ekani ham aytilmagan. c) — "va" bor: bu ikki commit bo'lishi kerak. Fe'l ham o'tgan zamonda ("tuzatdim").

6. Muharrirda xabar yozish va --verbose

6.1 Ko'p qatorli xabar

-m bir qatorli xabar uchun qulay. Tanali xabarni muharrirda yozish osonroq. Sarlavha o'zgarishini qo'shamiz va -m siz, --verbose (-v) bilan commit qilamiz:

bash
git add menyu/index.html
git commit --verbose

VS Code'da COMMIT_EDITMSG nomli fayl ochiladi (Vim darsida core.editor ni shunga sozlagan edik). Biz xabar yozishdan oldin fayl shunday ko'rinadi:

text

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch main
# Changes to be committed:
#	modified:   menyu/index.html
#
# ------------------------ >8 ------------------------
# Do not modify or remove the line above.
# Everything below it will be ignored.
diff --git a/menyu/index.html b/menyu/index.html
index 6af07ae..e4f0bdb 100644
--- a/menyu/index.html
+++ b/menyu/index.html
@@ -1,4 +1,4 @@
-<h1>Menyu</h1>
+<h1>Bahor menyusi</h1>
 <p>Osh — 35 000 so'm</p>
 <p>Lag'mon — 28 000 so'm</p>
 <p>Manti — 30 000 so'm</p>

Tarjimasi (tepadagi izoh): "O'zgarishlaringiz uchun commit xabarini kiriting. # bilan boshlangan qatorlar e'tiborga olinmaydi, bo'sh xabar esa commitni bekor qiladi." Pastda — status natijasi.

--verbose ning foydasi — qaychi chizig'idan (>8) pastdagi qism. Bu aynan commitga ketadigan o'zgarish: faqat sarlavha, manti yo'q (u allaqachon commit qilingan). Xabarni yozayotganda u ko'z oldingizda turadi. Tarjimasi (qaychi chizig'i): "Yuqoridagi qatorni o'zgartirmang va o'chirmang. Undan pastdagi hamma narsa e'tiborga olinmaydi" — farq xabarga tushmaydi.

Birinchi qatorga «Xabarning tuzilishi» bo'limidagi matnni yozamiz, saqlab, tabni yopamiz:

text
[main e979a8e] Menyu: sarlavhaga choyxona nomini qo'sh
 1 file changed, 1 insertion(+), 1 deletion(-)

1 insertion(+), 1 deletion(-) — bir qator qo'shildi, bittasi o'chdi. Sarlavhani almashtirish Git uchun aynan shunday ko'rinishini «Bo'lakni o'qish» bo'limida ko'rgan edik.

Maslahat: Har safar --verbose yozmaslik uchun uni doimiy qilish mumkin: git config --global commit.verbose true. Shunda git commit muharrirni har doim farq bilan ochadi.

6.2 Tanani tarixda ko'rish

bash
git log -1
text
commit e979a8eae29842426f3abef6661e8df4fdac0ff2 (HEAD -> main)
Author: Aziz Karimov <aziz@example.com>
Date:   Sat Oct 3 09:10:00 2026 +0500

    Menyu: sarlavhaga choyxona nomini qo'sh
    
    Mehmonlar menyu sahifasini ko'pincha Google'dan to'g'ridan-to'g'ri
    ochadi. Oddiy "Menyu" sarlavhasidan qaysi joy ekani bilinmasdi.

Tana to'liq saqlandi — xuddi siz yozgandek, 4 bo'sh joy surilgan holda. --oneline esa faqat sarlavhani ko'rsatadi:

bash
git log --oneline -3
text
e979a8e (HEAD -> main) Menyu: sarlavhaga choyxona nomini qo'sh
285ac84 Menyu: manti narxini qo'sh
e50f485 Bron: telefon raqamini qo'sh

Uch topshiriq — uch commit, har biri o'z nomi bilan. -3 — "oxirgi 3 ta commit". git log ning boshqa imkoniyatlarini Tarixni o'qish darsida ko'ramiz.

6.3 Terminalda tana: -m ikki marta

Muharrirsiz ham tana yozish mumkin. Ikkinchi -m — tana bo'ladi, Git ular orasiga bo'sh qatorni o'zi qo'yadi:

bash
git commit -m "Bosh sahifa: ish vaqtini qo'sh" \
  -m "Mehmonlar telefon qilib so'rayverishardi."

Qator oxiridagi \ — "buyruq keyingi qatorda davom etadi" (telefonda sig'ishi uchun; bitta qatorda yozsa ham bo'ladi). Buni sinov nusxada sinadik, «Bahor» tarixiga qo'shmaymiz. git log -1 da tana muharrirdagidek chiqadi:

text
    Bosh sahifa: ish vaqtini qo'sh
    
    Mehmonlar telefon qilib so'rayverishardi.

(commit, Author va Date qatorlarini tashlab ketdik.)

7. Fayl o'chirish va ko'chirish: git rm, git mv

7.1 Sinov nusxasi

Bu bo'limdagi tajribalarni «Bahor»ning asosiy reposida qilmaymiz. kurs/sinov-git/ — tashlab yuboriladigan tajribalar papkasi. «Bahor» papkasini u yerga nusxalaymiz (Fayl va papkalar bilan ishlash darsidagi cp -r):

bash
cd ~/kurs
mkdir -p sinov-git
cp -r bahor sinov-git/bahor
cd sinov-git/bahor

Papka bilan birga .git ham, ya'ni butun tarix ham nusxalanadi. Bu nusxadagi ishlar asl «Bahor» ga ta'sir qilmaydi.

7.2 Oddiy rm va git rm

Faraz qilaylik, aloqa sahifasi endi kerak emas. Avval oddiy rm bilan o'chiramiz:

bash
rm aloqa/index.html
git status -s
text
 D aloqa/index.html

D — o'ng ustunda: fayl diskdan o'chdi, lekin qutida bu o'zgarish yo'q. Uch hudud darsida xuddi shu holatni ko'rgan edik. O'chirish ham o'zgarish — uni ham qutiga solish kerak. Bunga git rm ishlatiladi:

bash
git rm aloqa/index.html
git status -s
text
rm 'aloqa/index.html'
D  aloqa/index.html

Endi D chap ustunda — o'chirish qutida. ls bilan qarasak, aloqa papkasi ham yo'qolgan: ichida boshqa fayl qolmagani uchun. Commit:

bash
git commit -m "Aloqa: sahifani o'chir"
text
[main 01e26b7] Aloqa: sahifani o'chir
 1 file changed, 1 deletion(-)
 delete mode 100644 aloqa/index.html

delete mode — create mode ning teskarisi. Fayl hozirgi holatdan o'chdi, lekin tarixdan emas: eski commitlarda u saqlanib turibdi.

Odatda rm ni alohida yozish shart emas. git rm fayl ikki ishni birdan qiladi: faylni diskdan o'chiradi va o'chirishni qutiga soladi. Papkani o'chirish uchun -r kerak: git rm -r papka.

7.3 O'zgartirilgan faylni git rm qilish

Git sizni ishingizni yo'qotishdan himoya qiladi. Faylni o'zgartirib, commit qilmasdan o'chirmoqchi bo'lsak:

text
error: the following file has local modifications:
    index.html
(use --cached to keep the file, or -f to force removal)

Tarjimasi: "xato: quyidagi faylda lokal o'zgarishlar bor: index.html (faylni saqlab qolish uchun --cached ishlating yoki majburan o'chirish uchun -f)". Commit qilinmagan o'zgarish tarixda yo'q — o'chsa, uni hech qayerdan qaytarib bo'lmaydi. Shuning uchun Git to'xtadi. Bu holatni sinov nusxasida index.html ga bir qator qo'shib, keyin git rm index.html yozib oldik.

Ikki yo'l bor. -f (force) — "bilaman, baribir o'chir". --cached esa faylni diskda qoldiradi, faqat Git kuzatuvidan chiqaradi. Ikkinchisi juda foydali — .gitignore darsida u bilan tasodifan commit qilingan maxfiy faylni repodan chiqaramiz.

7.4 git mv — nom o'zgartirish va ko'chirish

Rahmat sahifasini "chiroyli" manzilga — /bron/rahmat/ ga ko'chiramiz. Buning uchun fayl bron/rahmat/index.html bo'lishi kerak (Ko'p sahifali sayt tuzilmasi darsidagi index.html qoidasi):

bash
mkdir -p bron/rahmat
git mv bron/rahmat.html bron/rahmat/index.html
git status
text
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    bron/rahmat.html -> bron/rahmat/index.html

renamed — "nomi o'zgartirildi". Commit:

bash
git commit -m "Bron: rahmat sahifasini papkaga ko'chir"
text
[main 5473859] Bron: rahmat sahifasini papkaga ko'chir
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename bron/{rahmat.html => rahmat/index.html} (100%)

(100%) — fayl mazmuni 100% bir xil qoldi, faqat joyi o'zgardi. 0 insertions, 0 deletions — birorta qator o'zgarmadi.

7.5 Git nom o'zgarishini qanday "biladi"?

Git nom o'zgarishini alohida saqlamaydi. U faqat "eski yo'lda fayl yo'q, yangi yo'lda bor" deb yozadi va ikki faylning mazmunini solishtiradi. Ular yetarlicha o'xshash bo'lsa (odatiy chegara — 50%), Git buni renamed deb ko'rsatadi.

Shuning uchun git mv — shunchaki qulaylik. Oddiy mv bilan ham bir xil natija olasiz:

bash
mv menyu/index.html menyu/taomlar.html
git status -s
text
 D menyu/index.html
?? menyu/taomlar.html

Hozircha Git ikki alohida narsani ko'ryapti: bitta fayl o'chdi, bitta yangi paydo bo'ldi. Ikkalasini qutiga solamiz — git add menyu papkadagi o'chirishni ham, yangi faylni ham qo'shadi:

bash
git add menyu
git status -s
text
warning: in the working copy of 'menyu/taomlar.html', LF will be replaced by CRLF the next time Git touches it
R  menyu/index.html -> menyu/taomlar.html

R — renamed. Git mazmunga qarab o'zi topdi. git mv esa uchta buyruqni (mv, eski yo'lni git rm, yangisini git add) bittaga jamlaydi.

Bu nusxadagi tajribalar tugadi. sinov-git/bahor papkasini o'chirib tashlasangiz ham bo'ladi.

Tekshirib ko'ring: Faylni nomini o'zgartirib, ichidagi yarim qatorlarni ham qayta yozdingiz. Git buni renamed deb ko'rsatadimi?

Javob

Ehtimol yo'q. Git nom o'zgarishini mazmunning o'xshashligidan topadi. Mazmun ko'p o'zgarsa, u "bitta fayl o'chdi, boshqasi yaratildi" deb ko'rsatadi. Shuning uchun yaxshi amaliyot: avval faqat nomini o'zgartirib commit qiling, keyin mazmunini — alohida commitda. Bu ham atomar commit qoidasi.

8. Ko'p uchraydigan xatolar

8.1 Bitta qo'shtirnoq ichida apostrof

O'zbekcha xabarlarda bu eng ko'p uchraydigan tuzoq:

bash
git commit -m 'Menyu: lag'mon narxini yangila'

Terminal commit qilmaydi — > belgisini ko'rsatib, davomini kutadi. Bash ' belgisini qo'shtirnoq deb tushundi: lag dan keyingi ' qo'shtirnoqni yopdi, oxirgisi esa yangisini ochdi va u yopilmadi. Skriptda yoki buyruq bitta qatorda kelsa, xato to'g'ridan-to'g'ri chiqadi:

text
bash: -c: line 1: unexpected EOF while looking for matching `''

Tarjimasi: "kutilmagan fayl oxiri: juft ' qidirilayotgan edi". Tuzatish: Ctrl + C bilan chiqing va xabarni qo'sh qo'shtirnoqqa oling: git commit -m "Menyu: lag'mon narxini yangila". Qo'sh qo'shtirnoq ichida apostrof oddiy belgi. Bu darsdagi hamma xabarlar shuning uchun "..." ichida.

8.2 git add -p yangi faylni ko'rmaydi

bash
git add -p yangi.html
text
No changes.

Tarjimasi: "O'zgarishlar yo'q." Lekin fayl bor-ku? -p faqat Git taniydigan (tracked) fayldagi o'zgarishlarni bo'laklarga bo'ladi. Yangi fayl hali tanish emas. Tuzatish: yangi faylni oddiy git add yangi.html bilan qo'shing. Fayl o'zgarmagan bo'lsa ham xuddi shu xabar chiqadi.

8.3 "WIP", "fix", "yana"

"WIP" (work in progress — "ish davom etyapti"), "fix" kabi xabarlar ko'pincha shoshilishdan. Xabar yozish qiyin bo'lsa — ehtimol commit ichida bir necha ish aralash. git add -p bilan ajrating.

8.4 Xabar va mazmun mos emas

Oldingi darsdagi 3-mashqni eslang: "Sahifa va stil" xabarli commitda stil yo'q edi. Commitdan oldin git status ga, xabar yozayotganda --verbose farqiga qarang. Xabar qutidagini aytsin — xotirangizdagini emas.

8.5 Oxirgi commitda xato qildingizmi?

Xabarda imlo xatosi bo'ldi yoki bitta fayl unutildi — tushkunlikka tushmang. Oxirgi commitni tuzatish yo'li bor, uni Xatoni tuzatish 1 darsida o'rganamiz.

9. Mashqlar

1-mashq (oson): Yaxshi sarlavhani tanlang

Qaysi sarlavhalar kurs kelishuviga («Soha: buyruq maylidagi gap») va 50 belgi qoidasiga mos? Mos kelmaganini to'g'rilang.

  1. update
  2. Bron: sana maydonini qo'sh
  3. CSS: tugmalar rangini o'zgartirdim
  4. Menyu: narxlarni yangila, rasmlar qo'sh va footer'ni tuzat

Ishora: «Buyruq mayli» bo'limidagi jadval va «Qanchalik kichik?» dagi "va" testi.

Yechim
  1. Mos emas: soha yo'q, nima yangilangani noma'lum. Masalan: Menyu: narxlarni yangila.
  2. Mos — soha bor, fe'l buyruq maylida, 26 belgi.
  3. Fe'l o'tgan zamonda. To'g'risi: CSS: tugmalar rangini o'zgartir.
  4. 57 belgi va ikkita "va" — uchta ish. Uch commitga bo'ling: Menyu: narxlarni yangila, Menyu: taom rasmlarini qo'sh, Footer: ... tuzat (nima tuzatilganini aniq yozing).

2-mashq (o'rta): Bitta faylda ikki ish

«Bahor»ning sinov nusxasida menyuda ikki o'zgarish qiling: osh narxini 38 000 so'mga ko'taring (VS Code'da) va oxiriga chuchvara qo'shing:

bash
echo "<p>Chuchvara — 25 000 so'm</p>" >> menyu/index.html

Ikkalasini ikki commitga ajrating. Bo'sh joylarni to'ldiring:

bash
git add  menyu/index.html

Git birinchi bo'lakda ikkala o'zgarishni ko'rsatadi — uni bo'lish uchun [:s] yozasiz. Birinchi kichik bo'lak — osh narxi: [:y]. Ikkinchisi — chuchvara: .

bash
git commit -m "Menyu: osh narxini 38 000 so'mga ko'tar"
git add menyu/index.html
git commit -m "Menyu: chuchvara qo'sh"

Ishora: «git add -p — fayl ichidan tanlash» bo'limidagi javoblar jadvali.

Yechim

Javoblar: -p, keyin s, y, n. Biz sinab ko'rdik — s dan keyingi birinchi bo'lak:

text
@@ -1,4 +1,4 @@
 <h1>Bahor menyusi</h1>
-<p>Osh — 35 000 so'm</p>
+<p>Osh — 38 000 so'm</p>
 <p>Lag'mon — 28 000 so'm</p>
 <p>Manti — 30 000 so'm</p>

Commitlar va tarix:

text
[main 0873b08] Menyu: osh narxini 38 000 so'mga ko'tar
 1 file changed, 1 insertion(+), 1 deletion(-)
[main a573d5f] Menyu: chuchvara qo'sh
 1 file changed, 1 insertion(+)

Birinchi commitda 1 insertion(+), 1 deletion(-) — narx qatori almashtirildi. Ikkinchisida faqat qo'shish. Sizda SHA boshqacha bo'lishi mumkin.

3-mashq (qiyin): Stajyorning commitini qayta rejalash

Sardor bir kunda shularni qildi va hammasini bitta git commit -a -m "o'zgarishlar" bilan saqladi:

  • bron/index.html da telefon raqamidagi xatoni tuzatdi;
  • index.html va menyu/index.html ni Prettier bilan formatladi;
  • assets/css/asosiy.css ning nomini asosiy-yangi.css qildi, lekin HTML'dagi havolani o'zgartirmadi.
  1. Nechta commit bo'lishi kerak edi? Sarlavhalarini yozing.
  2. Qaysi ish umuman commit qilinmasligi kerak edi (yoki tugatilishi kerak edi) va nega?
  3. -a bu yerda yana qanday muammo tug'dirishi mumkin edi?

Ishora: «Qanchalik kichik?» bo'limidagi "har bir commitdan keyin loyiha ishlaydi" qoidasi va oldingi darsdagi -a tuzog'i.

Yechim
  1. Kamida ikkitasi aniq: Bron: telefon raqamidagi xatoni tuzat va Bosh sahifa va menyu: Prettier bilan formatla (formatlash — faqat formatlash, alohida).
  2. Nom o'zgarishi. Havola eski nomda qolgani uchun sayt stilsiz ochiladi. To'g'risi — nomni o'zgartirish va havolani yangilash bitta commitda: CSS: asosiy.css ni asosiy-yangi.css ga ko'chir. Buni git mv bilan qilish qulay.
  3. -a faqat tracked fayllarni qo'shadi. git mv o'rniga oddiy mv ishlatilgan bo'lsa, yangi nomli fayl untracked bo'ladi va commitga tushmaydi — eski fayl esa o'chiriladi. Natijada commitda CSS umuman qolmaydi.

4-mashq: Portfolio qadami — eski nusxani o'chiring va mashqlar reposini oching

Birinchi repo darsida portfolio'ni Git'ga o'tkazdik va asosiy-eski.css ni hozircha qoldirdik. Endi uni to'g'ri yo'l bilan o'chiramiz. Eski versiya yo'qolmaydi — u birinchi commitda turibdi.

  1. kurs/portfolio ga o'ting va git log --oneline ga qarang.
  2. asosiy-eski.css ni git rm bilan o'chiring va git status bilan tekshiring.
  3. git commit --verbose bilan, muharrirda, tanali xabar yozing. Sarlavha: CSS: eski zaxira nusxani o'chir. Tanada nega o'chirilganini 1–2 gapda yozing.
  4. git log --oneline va git log -1 bilan natijani ko'ring.
  5. Tekshiring: eski fayl haqiqatan tarixda qoldimi? Birinchi commitning SHA'si bilan: git show <sha>:asosiy-eski.css.

Ikkinchi qism — mashqlar repo. 03-qismdan beri kurs/mashqlar/ papkasida 05 va 06-qism mashqlari to'planib boryapti. Bugundan u ham Git reposi bo'ladi. 07-qism mashqlari mashqlar/07/<dars>/ papkalariga yoziladi va shu repoga commit qilinadi.

  1. kurs/mashqlar ga o'ting va git status bilan u hali repo emasligini tekshiring.
  2. 06-qismdagi ba'zi mashqlarda (masalan 06/tailwind/) node_modules/ bor. Shuning uchun avval .gitignore, keyin git init — Birinchi repo darsidagi portfolio tartibi.
  3. git add . dan keyin git status -s da node_modules yo'qligiga ishonch hosil qiling va commit qiling: Mashqlar: 05 va 06-qism mashqlarini qo'sh.
  4. 07/05-yaxshi-commit/javoblar.md faylini yarating va unga shu darsning 1-mashqi javoblarini yozing. Alohida commit: 07/05: yaxshi commit mashqlari javoblarini qo'sh. Bu repoda soha — mashq papkasi (07/05).
Yechim
bash
cd ~/kurs/portfolio
git log --oneline
git rm asosiy-eski.css
git status
git commit --verbose

Biz qisqa portfolio nusxasida sinadik. git rm va git status:

text
rm 'asosiy-eski.css'
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	deleted:    asosiy-eski.css

Muharrirda qaychi chizig'idan pastda o'chirilgan fayl ko'rinadi (sizda qatorlar ko'proq):

text
diff --git a/asosiy-eski.css b/asosiy-eski.css
deleted file mode 100644
index bc406f0..0000000
--- a/asosiy-eski.css
+++ /dev/null
@@ -1 +0,0 @@
-body { margin: 0; }

/dev/null — "hech narsa": fayl endi yo'q. Biz yozgan xabar:

text
CSS: eski zaxira nusxani o'chir

asosiy-eski.css 05-qismda zaxira sifatida qoldirilgan edi.
Endi eski holat Git tarixida saqlanadi, shuning uchun nusxa
fayl kerak emas.

Natija va tarix:

text
[main 6dbbf8c] CSS: eski zaxira nusxani o'chir
 1 file changed, 1 deletion(-)
 delete mode 100644 asosiy-eski.css
6dbbf8c (HEAD -> main) CSS: eski zaxira nusxani o'chir
63190c1 Portfolio: 06-qism oxiridagi holat

5-qadam — git show 63190c1:asosiy-eski.css faylning eski mazmunini chiqaradi (bizda body { margin: 0; }). Fayl hozirgi papkadan ketdi, lekin tarixdan emas. Sizda SHA boshqacha — o'zingizning birinchi commitingiz SHA'sini yozing.

Portfolio'da -eski, -nusxa, -final kabi boshqa fayllar bo'lsa, ular bilan ham shunday qiling — har biri uchun alohida commit shart emas, "eski nusxalarni o'chirish" bitta mantiqiy ish.

mashqlar repo:

bash
cd ~/kurs/mashqlar
git status
ls
echo 'node_modules/' > .gitignore
git init
git add .
git status -s
git commit -m "Mashqlar: 05 va 06-qism mashqlarini qo'sh"

Biz qisqa nusxada sinadik: 05/ da ikki mashq, 06/tailwind/ da node_modules va dist bilan. git status avval tanish xabarni beradi — fatal: not a git repository .... git add . dan keyin (CRLF ogohlantirishlarini tashlab ketdik):

text
A  .gitignore
A  05/flexbox/asosiy.css
A  05/flexbox/index.html
A  05/grid/asosiy.css
A  05/grid/index.html
A  06/tailwind/dist/chiqish.css
A  06/tailwind/index.html
A  06/tailwind/package.json

node_modules ro'yxatda yo'q — .gitignore ishladi. dist/chiqish.css esa commitga tushdi: uni Tailwind yaratgan, buni .gitignore darsida tuzatamiz. Sizda mashqlar ko'proq bo'ladi. Keyin javoblar fayli:

bash
mkdir -p 07/05-yaxshi-commit
code 07/05-yaxshi-commit/javoblar.md
git add 07
git commit -m "07/05: yaxshi commit mashqlari javoblarini qo'sh"
git log --oneline

code fayl — faylni VS Code'da ochadi (VS Code darsi). Javoblarni yozib, saqlang. Natija:

text
[main fb76752] 07/05: yaxshi commit mashqlari javoblarini qo'sh
 1 file changed, 6 insertions(+)
 create mode 100644 07/05-yaxshi-commit/javoblar.md
fb76752 (HEAD -> main) 07/05: yaxshi commit mashqlari javoblarini qo'sh
987f3ec Mashqlar: 05 va 06-qism mashqlarini qo'sh

Bundan keyingi darslarda har darsning mashqlari o'z papkasiga (07/06-git-log/, 07/07-git-diff/ ...) yoziladi va commit qilinadi.

10. Real ishda

  • Code review. Jamoada har bir o'zgarish Pull Request orqali ko'rib chiqiladi (Pull Request). Hamkasb commitlarni birma-bir o'qiydi. Atomar commitlar review'ni tezlashtiradi.
  • Bekor qilish. Xato commitni butunligicha teskari o'zgarish bilan bekor qilish mumkin (reset va revert). Commit atomar bo'lsa, faqat xato bekor qilinadi — yonidagi yaxshi ish qoladi.
  • Changelog. Reliz yozuvlari ko'pincha commit sarlavhalaridan avtomatik yig'iladi (Conventional Commits).
  • Intervyuda: "Yaxshi commit xabari qanday bo'ladi?", "Atomar commit nima?" — bu darsdan keyin misol bilan javob bera olasiz.

Xulosa

  • Atomar commit — bitta mantiqiy o'zgarish; har commitdan keyin loyiha ishlaydigan holatda.
  • Tavsifida "va" kerak bo'lsa — ikki commit.
  • git add -p bitta fayldagi o'zgarishlarni bo'lak-bo'lak tanlaydi: y, n, s, q.
  • Xabar: 50 belgigacha sarlavha buyruq maylida, bo'sh qator, kerak bo'lsa "nega" degan tana (72 belgili qatorlar).
  • git commit --verbose muharrirda aynan commitga ketayotgan farqni ko'rsatadi.
  • git rm va git mv o'chirish va ko'chirishni qutiga soladi; Git nom o'zgarishini mazmun o'xshashligidan topadi.

Keyingi dars: Tarixni o'qish: git log — to'plangan tarixdan kerakli commitni bir necha soniyada topishni o'rganamiz.

Manbalar

  • Git hujjati: "git-commit" (DISCUSSION bo'limi — 50 belgili birinchi qator), "git-add" (Interactive mode, patch), "git-rm", "git-mv" — git-scm.com/docs
  • Git hujjati: "SubmittingPatches" — buyruq maylida yozish tavsiyasi — git-scm.com/docs/SubmittingPatches
  • Pro Git kitobi: "Contributing to a Project" — Commit Guidelines — git-scm.com/book
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Yaxshi commit: atomar commit, git add -p va commit xabarini yozish — IlmHamroh