Asosiy kontentga o‘tish

Maqolalar 28 daqiqa 530 ko‘rish

git add nega kerak: fayl commitgacha uch bosqichdan o'tadi

Boshqa dasturlarda saqlash bitta tugma bilan bitadi. Git'da esa avval add, keyin commit qilamiz. Avvaliga bu ortiqcha qadamdek tuyulishi mumkin, lekin staging bejiz qo'shilmagan. Bu qismda buni amalda ko'ramiz: bitta faylni o'zgartirib, u bir vaqtning o'zida ikki xil holatda turishini tekshiramiz.

git devops

Mundarija

Oldingi qismda commitlar kim nomidan yozilishini sozlab oldik. Endi birinchi loyihamizni boshlaymiz.

To'g'ridan-to'g'ri shu qismdan boshlagan bo'lsangiz, bitta narsani tekshirib oling:

Terminal
git config --global user.name
git config --global user.email

Ulardan biri bo'sh chiqsa, git commit ishlamaydi yoki notanish nom bilan yoziladi — oldingi qismdagi sozlashni qilib keling. Buyruqlarni Windowsda Git Bashda, macOS va Linuxda esa oddiy terminalda yozasiz.

Lekin bu yerda bitta savol tug'iladi: nega avval git add, keyin git commit qilamiz? Boshqa dasturlarda saqlash uchun bitta tugma yetadi-ku.

Buni tushunish uchun kichik tajriba qilamiz: bitta faylni o'zgartirib, uni bir vaqtning o'zida ikkita ro'yxatda turgan holatda ko'ramiz. Shundan keyin add nega alohida qadam ekanini aniqroq tushunamiz.

Fayl uch joydan o'tadi#

Git'da fayl commitgacha uchta bosqichdan o'tadi:

Uch bosqich: 1) Ishchi papka — xarajat.py o'zgartirilgan (M), 2) Staging — git add bilan tanlangan (A), 3) Tarix — git commit bilan yozilgan (3 commit, main)
Fayl commit bo'lishidan oldin uchta bosqichdan o'tadi: ishchi papka, staging, tarix

Ishchi papka — kompyuteringizdagi haqiqiy fayllar. Faylni tahrirlaganingizda o'zgarish shu yerda paydo bo'ladi.

Staging — keyingi commit'ga kiritish uchun tanlab qo'yilgan o'zgarishlar. Git'dagi eng muhim tushunchalardan biri shu va boshida aynan shu joy biroz chalkash tuyuladi.

Tarix — commit qilingan va Git'da saqlanib qolgan holatlar.

Hozircha bular sizga nazariyadek tuyulishi mumkin. Keling, endi birgalikda amaliyotda sinab ko'ramiz.

git init — loyihani boshlaymiz#

Kunlik xarajatlarni yozib boradigan kichik dastur qilamiz. Dastur sodda bo'ladi, chunki bu yerda asosiy maqsad — Git qanday ishlashini amalda ko'rish.

Oldingi qismlardagi test-project bir martalik tajriba edi. Bu safar yaratadigan loyiha esa seriya oxirigacha biz bilan qoladi: keyingi qismlarda uni GitHub'ga chiqaramiz, branch ochamiz, conflict ham qilib ko'ramiz.

Terminalni oching va loyihalaringizni saqlaydigan papkada turing — uy papkangiz ham bo'ladi. Faqat boshqa Git loyihasining ichida bo'lmang, aks holda loyiha loyihaning ichida qolib ketadi.

Terminal
mkdir xarajat
cd xarajat
git init
# Initialized empty Git repository in /Users/siz/xarajat/.git/

Yo'l sizda boshqacha bo'ladi — muhimi, Initialized empty Git repository degan javob kelsin.

Shundan keyin papka ichida .git degan yashirin papka paydo bo'ladi. Ichiga qarab ko'ramiz:

Bo'lak Vazifasi
ls papka ichidagi fayllar ro'yxati
-1 ro'yxatni bitta ustunda chiqaradi
.git qaysi papka ko'rilayotgani
Terminal
ls -1 .git
Natija
HEAD
config
description
hooks
info
objects
refs

-1 siz ls fayllarni terminal kengligiga qarab ustunlarga bo'lib chiqaradi va ro'yxat boshqacha ko'rinadi. Tartib ham tizimingizga qarab o'zgarishi mumkin: ba'zi terminallarda HEAD boshida, ba'zilarida config va description orasida turadi. Muhimi — shu yettita nom bo'lsin.

Mana shu .git papkasi Git'ning asosiy xotirasi. Commitlar tarixi, sozlamalar va saqlangan holatlar shu yerda turadi. Uni o'chirsangiz, loyiha oddiy papkaga aylanadi va Git tarixi yo'qoladi.

Endi birinchi faylni yozamiz. Faylni istagan matn muharririda yarating — VS Code, Sublime, Notepad++ yoki terminalning o'zida nano xarajat.py. Muhimi: fayl nomi xarajat.py bo'lsin va u xarajat papkasining ichida yotsin.

Dasturni ishga tushirish shart emas, hatto Python o'rnatilmagan bo'lsa ham bemalol davom etaverasiz — bu qismda bizni faylning mazmuni emas, Git uni qanday kuzatishi qiziqtiradi.

xarajat.py
"""Kunlik xarajatlarni yozib boradigan kichik dastur."""

XARAJATLAR = []


def qoshish(summa, izoh):
    XARAJATLAR.append({"summa": summa, "izoh": izoh})


def jami():
    return sum(x["summa"] for x in XARAJATLAR)


if __name__ == "__main__":
    qoshish(12000, "Non va sut")
    qoshish(45000, "Taksi")
    print(f"Jami: {jami():,} so'm")

git status — Git nima ko'ryapti#

Ishni davom ettirishdan oldin hozir Git nimani ko'rayotganini tekshirib olamiz:

Terminal
git status
Natija
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    xarajat.py

nothing added to commit but untracked files present (use "git add" to track)

Birinchi qatorda On branch main deb turibdi. Sizda On branch master chiqsa ham xavotir olmang — bu shunchaki boshlang'ich branch nomi. Oldingi qismdagi init.defaultBranch sozlamasi qilinmagan bo'lsa shunday bo'ladi; maqoladagi qolgan hamma narsa baribir bir xil ishlayveradi.

Untracked — Git hali kuzatishni boshlamagan fayl degani. Git xarajat.py ni ko'rib turibdi, lekin uni hali o'z tarixiga qo'shmagan.

git status ning qisqa ko'rinishi ham bor. Kundalik ishlarda ko'pincha shu qulayroq:

Bo'lak Vazifasi
git status ishchi papka va staging holatini ko'rsatadi
-s qisqa ko'rinish (short): har fayl bitta qatorda
Terminal
git status -s
# ?? xarajat.py

?? — Git bu faylni hali kuzatmayapti degani.

git add — birinchi qadam#

Endi faylni staging'ga qo'shamiz. Buyruqning umumiy shakli:

Sintaksis
git add <fayl> [<fayl2> ...]

Burchakli qavs — siz qo'yadigan qiymat, kvadrat qavs — ixtiyoriy qism; qavslarning o'zi yozilmaydi.

Bo'lak Vazifasi
git add faylning hozirgi holatini staging'ga oladi
xarajat.py qaysi fayl olinayotgani (bir nechtasini bo'shliq bilan sanash mumkin)
Terminal
git add xarajat.py
git status
Natija
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
    new file:   xarajat.py

Endi sarlavha o'zgardi: Changes to be committed — ya'ni keyingi commit'ga kiradigan o'zgarishlar.

Demak, xarajat.py staging'ga tushdi.

Muhim joyi: fayl hali commit qilinmadi. Biz faqat uning hozirgi holatini keyingi commit'ga qo'shish uchun tanladik.

git diff — bitta fayl, ikkita holat#

Endi boshidagi savolga qaytamiz: nega add va commit alohida? Buni kichik tajriba bilan ko'ramiz.

Faylni yana bir marta o'zgartiramiz, lekin bu safar add qilmaymiz:

Terminal
echo "" >> xarajat.py
echo "# yangi qator" >> xarajat.py
git status -s

Bu yerda >> belgisi muhim: u faylning oxiriga qo'shadi. Bitta > bo'lsa, fayl butunlay o'chib, o'rniga faqat shu matn yozilardi. Ya'ni birinchi buyruq bo'sh qator, ikkinchisi esa # yangi qator degan izohni fayl oxiriga yopishtirdi. Xohlasangiz, xuddi shu ikki qatorni faylni muharrirda ochib qo'lda ham yozishingiz mumkin — farqi yo'q.

Natija
AM xarajat.py

Bu safar ikkita harf chiqdi. Aynan shu holat add nima uchun kerakligini ko'rsatadi.

Bitta faylning ikkita holati bor:

  • A (chapdagi harf) — faylning staging'ga qo'shilgan holati
  • M (o'ngdagi harf) — ishchi papkada fayl yana o'zgargan

To'liq holatni ko'rsak, bu yanada aniq ko'rinadi:

Terminal
git status
Natija
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
    new file:   xarajat.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   xarajat.py

Bitta fayl bir vaqtning o'zida ikkita ro'yxatda turibdi.

Bu xato emas. git add qilganimizda Git faylning o'sha paytdagi holatini staging'ga oladi. Keyin faylni yana o'zgartirsak, staging'dagi holat o'zgarib ketmaydi.

Bu ikki holatning farqini alohida ko'rishimiz mumkin:

Terminal
git diff
Natija
diff --git a/xarajat.py b/xarajat.py
index 3c93047..5c8f79d 100644
--- a/xarajat.py
+++ b/xarajat.py
@@ -15,3 +15,5 @@ if __name__ == "__main__":
     qoshish(12000, "Non va sut")
     qoshish(45000, "Taksi")
     print(f"Jami: {jami():,} so'm")
+
+# yangi qator

Boshidagi to'rt qator — Git'ning texnik sarlavhasi: qaysi fayl, qaysi holatlar solishtirilyapti. Pastdagi + belgili qatorlar esa aynan bizning o'zgarishimiz.

git diff — staging'ga hali qo'shilmagan o'zgarishlarni ko'rsatadi. Ya'ni hozir faylda nima o'zgardi, lekin add qilinmadi?

Bo'lak Vazifasi
git diff ishchi papka bilan staging o'rtasidagi farq
git diff --staged staging bilan oxirgi commit o'rtasidagi farq

Endi staging'dagi holatni ko'ramiz:

Terminal
git diff --staged
Natija
diff --git a/xarajat.py b/xarajat.py
new file mode 100644
index 0000000..3c93047
--- /dev/null
+++ b/xarajat.py
@@ -0,0 +1,17 @@
+"""Kunlik xarajatlarni yozib boradigan kichik dastur."""
+
+XARAJATLAR = []
...

Bu yerda chiqishning faqat boshini keltirdim — davomida faylning qolgan qatorlari turadi, hammasi + bilan.

git diff --staged esa staging'ga tushgan o'zgarishlarni ko'rsatadi. Ya'ni hozir commit qilsak, tarixga nima yoziladi?

git commit — tarixga yozamiz#

Endi staging'dagi holatni commit qilamiz:

Sintaksis
git commit -m "<izoh>"
Bo'lak Vazifasi
git commit staging'dagi holatni tarixga yozadi
-m "izoh" commit izohini shu yerda beradi (message)

-m ni yozishni unutsangiz, Git izoh so'rab matn muharririni ochadi va undan chiqish alohida ish bo'ladi — shuning uchun izohni doim shu yerda yozgan ma'qul. Agar baribir terminalda tushunarsiz oyna ochilib qolsa, bu ko'pincha Vim bo'ladi: Esc ni bosing, :q! deb yozing va Enter bosing. Commit bekor bo'ladi, keyin buyruqni -m bilan qayta yozasiz.

Terminal
git commit -m "Xarajat qo'shish va jami hisoblash"
# [main (root-commit) d291ac2] Xarajat qo'shish va jami hisoblash
#  1 file changed, 17 insertions(+)
#  create mode 100644 xarajat.py

17 qator commit qilindi. Endi tekshirib ko'ramiz: # yangi qator ham commitga tushdimi?

Commit ichidagi faylning oxirgi uch qatorini ko'ramiz:

Sintaksis
git show <commit>:<fayl>
Bo'lak Vazifasi
git show commitdagi narsani ko'rsatadi
HEAD:xarajat.py oxirgi commitdagi shu fayl (ishchi papkadagi emas)
quvur belgisi chapdagi buyruqning chiqishini o'ngdagiga uzatadi
tail -3 chiqishning oxirgi uchta qatorini oladi
Terminal
git show HEAD:xarajat.py | tail -3
#     qoshish(12000, "Non va sut")
#     qoshish(45000, "Taksi")
#     print(f"Jami: {jami():,} so'm")

# yangi qator yo'q. Chunki commitga ishchi papkadagi eng oxirgi holat emas, staging'ga add qilganimizdagi holat tushdi.

Lekin keyin yozgan o'zgarishimiz ham yo'qolmadi. U hali ham faylda turibdi:

Terminal
git status -s
#  M xarajat.py

Bu safar M o'ng tomonda turibdi. Chap tomon bo'sh — staging'da o'zgarish yo'q. O'ng tomondagi M esa ishchi papkada hali commit qilinmagan o'zgarish borligini bildiradi.

git status -s da harfning joyi muhim: chapdagi ustun — staging, o'ngdagi ustun — ishchi papka.

Staging nega kerak?#

Endi git add nega alohida qadam ekanini ko'rdik.

Tasavvur qiling, bir necha soat ishladik. Bitta fayldagi yangi funksiya tayyor, boshqa fayldagi o'zgarish esa hali tugallanmagan. Ikkalasini bitta commitga qo'shsak, keyin tarixni o'qish qiyinlashadi.

Staging shu yerda yordam beradi: tayyor bo'lgan o'zgarishlarni add qilamiz, qolganlarini esa hozircha qoldiramiz. Commit faqat staging'ga tanlangan o'zgarishlarni oladi.

Demak, add ortiqcha qadam emas. U commitga aynan qaysi o'zgarishlarni kiritishni tanlash imkonini beradi.

Ikkinchi commit#

Avval tajriba uchun qo'shgan # yangi qator ni tozalab olamiz. Faylni ochib, o'sha qatorni va undan oldingi bo'sh qatorni o'chiring.

Keyin holatni tekshiramiz:

Terminal
git status -s

Agar hech narsa chiqmasa, demak ishchi papka commitdagi holat bilan bir xil. Hali ham M xarajat.py chiqsa, git diff bilan nima ortib qolganini ko'ring — odatda bu o'chirilmay qolgan bo'sh qator bo'ladi.

Endi dasturga yana bitta funksiya qo'shamiz. Uni if __name__ == "__main__": blokidan oldin yozamiz — funksiyalar dastur ishga tushadigan qismdan yuqorida turgani tartibliroq bo'ladi. Boshqa funksiyalardagidek, undan oldin ikkita bo'sh qator qoldiring:

xarajat.py
def eng_katta():
    """Eng qimmat xarajatni qaytaradi."""
    return max(XARAJATLAR, key=lambda x: x["summa"], default=None)

So'ng o'zgarishni staging'ga qo'shib, ikkinchi commitni qilamiz:

Terminal
git add xarajat.py
git commit -m "Eng qimmat xarajatni topish"

git log — tarixni o'qiymiz#

Endi ikkita commitimiz bor. Ularni git log orqali ko'ramiz:

Terminal
git log

Tarix uzun bo'lsa, Git chiqishni ko'ruvchi dastur ichida ochadi: strelkalar bilan aylantirasiz, q bosib chiqasiz. Hozir ikkita commit bor, shuning uchun u to'g'ridan-to'g'ri terminalga chiqadi.

Natija
commit b41bd9b2df239963b33687f1e9f7f75f0e65ea60
Author: Asadbek Solijonov <109437399+AsadbekSolijonov@users.noreply.github.com>
Date:   Fri Aug 21 22:09:37 2026 +0500

    Eng qimmat xarajatni topish

commit d291ac2e7b2d919f71b2cbe37433d1229f83dd7f
Author: Asadbek Solijonov <109437399+AsadbekSolijonov@users.noreply.github.com>
Date:   Fri Aug 21 21:52:02 2026 +0500

    Xarajat qo'shish va jami hisoblash

Oldingi qismda sozlagan ism va emailimiz shu yerda ko'rinadi. Har bir commitda uni kim qilgani, qachon qilingani va qanday izoh yozilgani saqlanadi.

Boshidagi uzun belgi esa commitning identifikatori. Git har bir commitga alohida hash beradi va kerak bo'lsa, aynan shu hash orqali o'sha commitga murojaat qilamiz.

Kundalik ishlarda tarixning qisqa ko'rinishi qulayroq:

Bo'lak Vazifasi
git log commitlar tarixi, eng yangisi tepada
--oneline har commit bitta qatorda: qisqa hash va izoh
Terminal
git log --oneline
# b41bd9b Eng qimmat xarajatni topish
# d291ac2 Xarajat qo'shish va jami hisoblash

Bu yerda commit hashining qisqa ko'rinishi va yonida commit izohi turibdi.

Bitta commitda nimalar o'zgarganini ko'rish uchun:

Bo'lak Vazifasi
--stat qaysi fayl necha qatorga o'zgarganini sanab beradi
--oneline commit sarlavhasini bitta qatorga siqadi
HEAD qaysi commit ko'rilayotgani — bu yerda oxirgisi
Terminal
git show --stat --oneline HEAD
# b41bd9b Eng qimmat xarajatni topish
#  xarajat.py | 5 +++++
#  1 file changed, 5 insertions(+)

HEAD hozir turgan eng oxirgi commitni bildiradi. Natijadan ko'rinib turibdi: oxirgi commitda xarajat.py fayliga 5 ta qator qo'shilgan.

git add — ikkita fayl bilan sinaymiz#

Yuqorida "tayyor o'zgarishni tanlab olasiz" deb aytdim. Bitta fayl bilan buni his qilish qiyin, shuning uchun endi ikkita fayl bilan ishlaymiz.

Loyihaga hisobot moduli qo'shamiz — yangi fayl yarating:

hisobot.py
"""Xarajatlar bo'yicha qisqa hisobot chiqaradi."""


def hisobot(xarajatlar):
    for x in xarajatlar:
        print(f"{x['izoh']:<20} {x['summa']:>8,}")

Shu bilan birga xarajat.py ni ham oching va oxiriga hali tugatilmagan ish haqida eslatma yozib qo'ying:

xarajat.py
# TODO: xarajatni o'chirish funksiyasi ham kerak

Endi holat hayotdagidek: bitta ish tayyor, ikkinchisi esa yarim yo'lda. Git nima ko'ryapti?

Terminal
git status -s
#  M xarajat.py
# ?? hisobot.py

Ikkalasi ham commitdan tashqarida. Lekin bizga faqat bittasi kerak, shuning uchun faqat hisobotni staging'ga qo'yamiz:

Terminal
git add hisobot.py
git status -s
# A  hisobot.py
#  M xarajat.py

A — yangi fayl staging'da (inglizcha added). xarajat.py esa o'ng ustunda qolib ketdi, ya'ni unga tegilmadi. Commit qilamiz:

Terminal
git commit -m "Xarajatlar hisoboti uchun alohida modul"
# [main 5a331f4] Xarajatlar hisoboti uchun alohida modul
#  1 file changed, 6 insertions(+)
#  create mode 100644 hisobot.py

E'tibor bering: 1 file changed. Ikkita faylni o'zgartirgan bo'lsak ham, tarixga bittasi tushdi. Tekshirib ko'ramiz:

Terminal
git show --stat --oneline HEAD
git status -s
Natija
5a331f4 Xarajatlar hisoboti uchun alohida modul
 hisobot.py | 6 ++++++
 1 file changed, 6 insertions(+)
 M xarajat.py

Mana shu — add nega alohida qadam ekanining butun javobi. Tugallanmagan ish ishchi papkada xotirjam yotibdi, tarixga esa faqat tayyori yozildi. Bitta tugmali "saqlash" bunday qila olmaydi: u hamma narsani birdan oladi.

Commit izohi haqida ikki og'iz#

Izoh — kelajakdagi o'zingizga yozilgan xat. Olti oydan keyin kodni ochganingizda git log da faqat shu izohlar qoladi, boshqa hech narsa esda turmaydi.

Ikkita qoida yetarli. Birinchisi: faylni emas, qilingan ishni yozing — qaysi fayl o'zgarganini Git o'zi biladi. Ikkinchisi: bitta commit — bitta ish; izohda "va" so'zi ko'payib ketsa, demak uni ikkita commitga bo'lish kerak edi.

Yomon izoh Nega yomon Yaxshisi
update nima yangilandi? Hisobot modulini qo'shish
fix nima tuzatildi? Jami hisoblashdagi xatoni tuzatish
xarajat.py fayl nomini Git biladi Eng qimmat xarajatni topish

git restore — orqaga qaytarish#

Oldingi bo'limdan xarajat.py da commit qilinmagan o'zgarish qolib ketdi — o'sha TODO eslatmasi. Aynan shu bilan uchta holatni mashq qilamiz.

Bu bo'limda ishlatadigan buyruqning shakli:

Sintaksis
git restore [--staged] <fayl>

Birinchi holat: add qildik, lekin fikrimizdan qaytdik. Avval faylni staging'ga qo'yamiz:

Terminal
git add xarajat.py
git status -s
# M  xarajat.py

Fayl staging'da turibdi.

Endi uni staging'dan chiqaramiz:

Bo'lak Vazifasi
git restore faylni oxirgi saqlangan holatiga qaytaradi
--staged faqat staging'dan chiqaradi, fayl o'zgarishsiz qoladi
xarajat.py qaysi fayl
Terminal
git restore --staged xarajat.py
git status -s
#  M xarajat.py

Harf o'ng tomonga ko'chdi. O'zgarish yo'qolmadi — faqat staging'dan chiqdi va ishchi papkada qolib ketdi.

Ikkinchi holat: o'zgarishning o'zi kerak emas. Bu safar uni butunlay bekor qilamiz:

Terminal
git restore xarajat.py
git status -s

Hech narsa chiqmadi — demak ishchi papka oxirgi commitdagi holat bilan bir xil.

Bu buyruqda ehtiyot bo'lish kerak: git restore commit qilinmagan o'zgarishni butunlay o'chiradi. Git'ga tushmagan o'zgarishni keyin qaytarib bo'lmaydi.

Uchinchi holat: faylni butunlay o'chirib yubordingiz. Bu eng qo'rqinchli ko'rinadigan holat, shuning uchun uni ataylab qilib ko'ramiz:

Terminal
rm xarajat.py
git status -s
#  D xarajat.py

D — deleted, ya'ni Git faylning yo'q bo'lganini payqadi. Papkani ochib qarasangiz, fayl rostdan yo'q. Endi:

Terminal
git restore xarajat.py
git status -s
ls -1
# hisobot.py
# xarajat.py

git status -s hech narsa chiqarmadi va fayl joyiga qaytdi. Chunki uning oxirgi commitdagi nusxasi .git ichida saqlanib turgan edi.

Aynan shu — Git nima uchun kerakligining eng sodda javobi. Faqat bitta shart bilan: commit qilingan bo'lsa. Hech qachon commit qilinmagan faylni Git ham qaytara olmaydi.

Endi buzib ko'ring#

Ixtiyoriy bo'lim

Vaqtingiz tig'iz bo'lsa, bu bo'limni o'tkazib yuborib keyinroq qaytsangiz bo'ladi — maqolaning davomi bunga bog'liq emas.

Tushunganingizni tekshirish uchun bir nechta joyni ataylab o'zgartirib ko'ramiz.

Mashqlarni xarajat ichida emas, alohida sinov papkasida bajaring. Aks holda loyiha tarixiga ortiqcha commitlar tushadi va keyingi qismlardagi natijalar maqoladagidan farq qiladi:

Terminal
cd ..
mkdir mashq
cd mashq
git init
  1. Fayl yarating va commit qiling. Keyin uni o'zgartiring, add qiling va yana o'zgartiring.

    git status -s nima ko'rsatadi? git diff va git diff --staged bir xil natija beradimi?

    Kutilgan natija: MM bir.txt — ikkala ustunda ham harf. git diff faqat ikkinchi o'zgarishni, git diff --staged esa faqat birinchisini ko'rsatadi.

  2. Ikkita fayl yarating (masalan, ikki.txt va boshqa.txt), faqat bittasini add qiling va commit qiling.

    Ikkinchi fayl commitga tushadimi? git status nima ko'rsatadi?

    Kutilgan natija: commitdan keyin ham add qilinmagan fayl ?? bilan turaveradi. Git add qilinmagan faylni o'z ixtiyori bilan olmaydi.

  3. Yangi uch.txt yarating, git add qilib, keyin faylni butunlay o'chiring.

    Commit qilsangiz nima bo'ladi? Fayl tarixda qoladimi?

    Kutilgan natija: o'chirgandan keyin AD uch.txt chiqadi. Commit qilsangiz, fayl tarixga tushadi (git show --stat da ko'rinadi), lekin ishchi papkada yo'q bo'lgani uchun git status uni D deb ko'rsatadi. Ya'ni Git commitga staging'dagi nusxani yozadi, papkadagi holatni emas.

  4. .git papkasini boshqa joyga ko'chiring va git status yozing.

    Qanday xato chiqadi? Shu tajribadan keyin .git papkasining vazifasi yanada aniqroq bo'ladi.

    Kutilgan natija: fatal: not a git repository (or any of the parent directories): .git. Papkani qaytarib qo'ysangiz, hammasi joyiga tushadi — loyihaning butun tarixi aynan shu papkada yotadi.

Mashq tugagach, cd ../xarajat bilan loyihangizga qayting. mashq papkasi endi kerak emas, uni o'chirib tashlashingiz mumkin.

git clone — qilingan ishni tekshirish#

Ixtiyoriy bo'lim

Vaqtingiz tig'iz bo'lsa, bu bo'limni o'tkazib yuborib keyinroq qaytsangiz bo'ladi — maqolaning davomi bunga bog'liq emas.

Yuqoridagi uchta commit shunchaki misol uchun yozilmagan. Ular mashq repozitoriysida turibdi va ularni o'zingiz ham ochib ko'rishingiz mumkin. Buning uchun ikkita yangi buyruq kerak:

Sintaksis
git clone <manzil>
git checkout <tag yoki branch>
Bo'lak Vazifasi
git clone <manzil> internetdagi repozitoriyani butun tarixi bilan nusxalaydi
git checkout qism-3 o'sha nusxa ichida qism-3 belgisi qo'yilgan holatga o'tadi

Faqat avval o'z loyihangizdan chiqib oling — aks holda git-darslik sizning xarajat loyihangizning ichiga tushib qoladi:

Terminal
cd ..
git clone https://github.com/AsadbekSolijonov/git-darslik.git
cd git-darslik
git checkout qism-3
git log --oneline
# 5a331f4 Xarajatlar hisoboti uchun alohida modul
# b41bd9b Eng qimmat xarajatni topish
# d291ac2 Xarajat qo'shish va jami hisoblash

Yuqorida faqat oxirgi buyruqning natijasi keltirilgan: git clone ham, git checkout ham o'zidan bir necha qator yozib qoldiradi.

Hashlar ham, commit izohlari ham maqoladagi bilan bir xil — chunki bular o'sha commitlarning o'zi. Papkada xarajat.py bilan hisobot.py yonma-yon turibdi, git show 5a331f4 esa oxirgi commitda aynan nima qo'shilganini ko'rsatadi.

Agar Git detached HEAD haqida ogohlantirsa, bundan xavotir olmang. Bu hozir branchning oxirida emas, aniq bir commit holatida turganingizni bildiradi. git switch xarajat bilan loyihaning oxirgi holatiga qaytishingiz mumkin.

Siz yaratgan commitlarning hashleri boshqacha chiqishi normal. Hash faqat fayl mazmuniga emas, commit vaqti va muallif kabi ma'lumotlarga ham bog'liq. Shu sabab bir xil o'zgarishlarni qilsak ham, hashlar bir xil bo'lishi shart emas.

Boshidagi muammoga qaytamiz#

Seriya shu ro'yxatdan boshlangan edi:

Fayl tuzilishi
kurs_loyiha/
kurs_loyiha_yangi/
kurs_loyiha_final/
kurs_loyiha_final_v2/
kurs_loyiha_final_v2_oxirgi/
kurs_loyiha_ISHLAYDIGAN_shu/

Endi o'sha narsa boshqacha ko'rinadi. Papka bitta, tarix esa uning ichida. Mashq repozitoriysini ko'rgan bo'lsangiz, avval o'z loyihangizga qayting:

Terminal
cd ../xarajat
git log --oneline
# 5a331f4 Xarajatlar hisoboti uchun alohida modul
# b41bd9b Eng qimmat xarajatni topish
# d291ac2 Xarajat qo'shish va jami hisoblash

Farqni ko'ryapsizmi? Papka nomlari sizga hech narsa aytmaydi — qaysi biri oxirgisi, v2 da nima o'zgargan edi, buni faqat esda saqlash kerak. Commit ro'yxati esa har bir qadamda nima qilinganini o'zi aytib turibdi.

Demak, endi nusxa papka yaratish shart emas. "Ishlayotgan holatni saqlab qo'yay" degan tuyg'u kelsa — commit qilasiz. Papkalar ko'paymaydi, tarix esa saqlanib boraveradi.

Shu xatolar chiqsa#

Yangi boshlaganda vaqtning ko'p qismi buyruq yozishga emas, xatoni tushunishga ketadi. Quyidagilar eng ko'p uchraydiganlari — men ularni ataylab chiqarib, matnini shu yerga ko'chirdim.

Xabar Sababi Yechimi
fatal: not a git repository (or any of the parent directories): .git Buyruqni loyiha papkasidan tashqarida yozdingiz cd xarajat bilan loyihaga qayting
fatal: pathspec 'xarajat.py' did not match any files git add faylni topolmadi: nomida xato yoki boshqa papkadasiz ls -1 bilan fayl nomini va joyingizni tekshiring
nothing to commit, working tree clean Commit qilinadigan o'zgarish yo'q Avval faylni o'zgartiring, keyin git add
nothing added to commit but untracked files present Fayl bor, lekin git add qilinmagan git add <fayl>
Aborting commit due to empty commit message. -m siz commit qildingiz va izoh yozilmadi git commit -m "izoh" shaklida yozing
error: pathspec '...' did not match any file(s) known to git git restore Git bilmaydigan faylni tiklay olmaydi Bu fayl hech qachon commit qilinmagan — Git uni qaytara olmaydi
warning: ... LF will be replaced by CRLF ... Windows va Unix qator oxirini har xil belgilaydi Xato emas — Git buni o'zi moslashtiradi, davom etavering

Xato chiqsa, avval oxirgi qatorni o'qing: Git odatda muammoni ham, yechimni ham o'sha yerda aytadi.

Shu qismning buyruqlari#

Buyruq Vazifasi
git init Papkani Git loyihasiga aylantirish
git status Hozirgi holat: nima o'zgargan, nima staging'da
git status -s Shu holatning qisqa ko'rinishi
git add <fayl> Faylni staging'ga qo'shish
git diff Staging'ga tushmagan o'zgarishlar
git diff --staged Staging'dagi o'zgarishlar
git commit -m "izoh" Staging'dagi holatni tarixga yozish
git log Commit tarixi
git log --oneline Tarixning qisqa ko'rinishi
git show HEAD:<fayl> Commitdagi faylni ochish
git restore --staged <fayl> Staging'dan chiqarish, o'zgarish esa qoladi
git restore <fayl> O'zgarishni butunlay bekor qilish ⚠️
git show --stat HEAD Oxirgi commitda qaysi fayl necha qator o'zgargani

Bu qismda Git'niki bo'lmagan, oddiy terminal buyruqlari ham uchradi. Ular Git'ga aloqasiz, lekin har kuni kerak bo'ladi:

Buyruq Vazifasi
mkdir <papka> Yangi papka yaratish
cd <papka> Papka ichiga kirish (cd .. — bir pog'ona yuqoriga)
ls -1 <papka> Ichidagi fayllar ro'yxati, bitta ustunda
echo "matn" >> fayl Fayl oxiriga qator qo'shish (> esa faylni almashtiradi)
tail -3 Buyruq chiqishining oxirgi uch qatori (quvur orqali ishlatiladi)
rm <fayl> Faylni o'chirish

Keyingi qismda#

Endi loyihamiz ham, commitlar tariximiz ham bor. Lekin hozircha bularning hammasi faqat kompyuterimizda turibdi. Agar kompyuter bilan muammo bo'lsa, loyiha tarixi ham birga yo'qolishi mumkin.

Keyingi qismda loyihani GitHub'ga chiqaramiz: SSH kalit yaratamiz, .gitignore bilan kerakmas va maxfiy fayllarni repoga tushirmaymiz, keyin birinchi push ni qilamiz. Shu jarayonda amalda tez-tez uchraydigan xatolarni ham birga ko'ramiz.

Yo'lda kerak bo'ladigan ma'lumotnoma#

Darslar ketma-ket boradi, lekin ba'zan bitta buyruq yoki atama haqida to'liq ma'lumot kerak bo'lib qoladi. Buning uchun Git'ning rasmiy qo'llanmasi o'zbekchaga o'girilgan: dars emas, kerak bo'lganda ochib, kerakli joyini o'qiydigan ma'lumotnoma. Ichida buyruqlar ro'yxati, savol-javob, atamalar lug'ati va Git ichki tuzilishi bor.

Keyingi o'qish: Git rasmiy qo'llanmasiGit bilan tanishuv: rasmiy qo‘llanmaMaqola · 15 daqiqa
28 daqiqa 530 marta o‘qildi