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

Git remote: clone, fetch, pull va push — repo'ni GitHub bilan bog'lash

Qisqacha: Remote — repo'ning boshqa joydagi (odatda GitHub'dagi) nusxasi, odatiy nomi origin. Bog'lash — git remote add origin <manzil>, birinchi yuborish — git push -u origin main. Reponi butun tarixi bilan olish — git clone. Fetch yangiliklarni faqat olib keladi va origin/main ni yangilaydi, pull esa olib keladi va birlashtiradi. Status'dagi ahead/behind — oxirgi fetch paytidagi holat bilan solishtirish.

Bu darsda

  • git remote add, git remote -v bilan repo'ni GitHub'ga bog'laysiz va git push -u bilan birinchi marta yuborasiz.
  • origin/main nima ekanini va u qachon yangilanishini tushuntira olasiz.
  • git clone, git fetch, git pull farqini real misolda ko'rasiz.
  • ahead 1, behind 1 kabi yozuvlarni o'qiysiz va yangi branchni GitHub'ga yuborasiz.
  • Brauzer orqali yuklangan login.github.io repongizni lokal tarix bilan saytni buzmasdan almashtirasiz.

Oldin bilishingiz kerak: SSH kalit va GitHub autentifikatsiyasi, Branch nima: arzon ko'rsatkich, HEAD, refs va detached HEAD.

1. Nega bu kerak?

Hozircha «Bahor» tarixi faqat Azizning noutbukida. Noutbuk buzilsa — tarix ham ketadi (Versiya nazorati darsidagi ogohlantirish). Stajyor Sardor ham sayt ustida ishlashi kerak, lekin u Azizning papkasini ko'ra olmaydi. Portfolio esa hali ham brauzer orqali, fayl-fayl yuklanyapti.

Uchala muammoning yechimi bitta: repo'ning GitHub'dagi nusxasi. Unga commitlarni yuborasiz, undan olasiz, boshqalar ham shu nusxa orqali ishlaydi.

Remote (masofaviy repo) — sizning repongizning boshqa joydagi nusxasi. Bir oiladagi umumiy daftarni tasavvur qiling: har kim uyda o'z daftarida yozadi, kechqurun umumiy daftarga ko'chiradi va undan boshqalarning yozganini oladi.

flowchart LR
  subgraph K["Kompyuter"]
    W["Ishchi papka"] --> L["main"]
    L -.- O["origin/main<br/>(oxirgi ko'rgan holat)"]
  end
  G[("GitHub<br/>main")]
  L -- "git push" --> G
  G -- "git fetch" --> O
  O -- "git merge" --> L

Nimaga qarang: GitHub bilan faqat ikki buyruq gaplashadi — push (yuborish) va fetch (olib kelish). Qolgan hamma ish — merge, status, log — kompyuteringiz ichida. pull esa fetch va merge ning birikmasi.

2. Remote qo'shish

2.1 GitHub'da bo'sh repo

Avval GitHub'da «Bahor» uchun bo'sh repo yaratiladi: + → New repository, nomi bahor, Public. GitHub hujjati muhim ogohlantirish beradi: mavjud loyihani olib kelayotgan bo'lsangiz, README, .gitignore va litsenziyani qo'shmang — aks holda GitHub'da sizda yo'q commit paydo bo'ladi va birinchi push'ning o'zi conflictga uchraydi. Repo bo'sh bo'lsin. Repo yaratishning boshqa tafsilotlarini GitHub asoslari darsida ko'rasiz.

Yaratilgach, sahifada repo manzili ko'rinadi. HTTPS shakli: https://github.com/login/bahor.git (login — sizning loginingiz).

2.2 git remote add

Repo hozir hech qayerga bog'lanmagan. Tekshiramiz va adashib yuborib ko'ramiz:

bash
cd ~/kurs/bahor
git remote -v
git push
text
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

    git remote add <name> <url>

and then push using the remote name

    git push <name>

git remote -v hech narsa chiqarmadi — remote yo'q. git push esa: "halokatli xato: yuborish manzili sozlanmagan". Git o'zi yo'l ko'rsatyapti: git remote add <nom> <manzil>. Bajaramiz:

bash
git remote add origin https://github.com/login/bahor.git
git remote -v
text
origin	https://github.com/login/bahor.git (fetch)
origin	https://github.com/login/bahor.git (push)
  • origin — remote'ning nomi: uzun manzil o'rniga qisqa laqab. Nomni o'zingiz tanlaysiz, lekin dunyo bo'yicha kelishuv — asosiy remote origin.
  • (fetch) va (push) — olib kelish va yuborish manzillari. Odatda bir xil.

Biz bu darsdagi barcha GitHub buyruqlarini vaqtinchalik sinov reposida ishga tushirdik. Chiqishlardagi repo nomini login/bahor ga almashtirdik — qolgan hammasi aynan terminaldagidek. Sinov reposidagi «Bahor» tarixi qisqa va oldinroq yozilgan: unda Birinchi repo darsidagi commitlar qisqaroq nomlar bilan turibdi (Aloqa sahifasi, Bosh sahifa: aloqa havolasi). Sizda o'sha darsdagi nomlar va SHA'lar bo'ladi — buyruqlar va natijaning shakli esa bir xil.

3. Birinchi push: git push -u origin main

bash
git push -u origin main
text
To https://github.com/login/bahor.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

Agar bu kompyuterda GitHub'ga birinchi marta HTTPS orqali ulanayotgan bo'lsangiz, shu yerda Git Credential Manager oynasi ochiladi (SSH kalit va autentifikatsiya darsidagi tartib). Bir marta kirasiz — qolgan push'lar so'roqsiz o'tadi.

Qatorma-qator:

  • To https://... — qayerga yuborildi.
  • * [new branch] main -> main — GitHub'da yangi branch yaratildi: lokal main → GitHub'dagi main.
  • branch 'main' set up to track 'origin/main' — "main branchi origin/main ni kuzatadigan qilib sozlandi". Buni -u qildi.

-u (--set-upstream) — "shu branchning GitHub'dagi jufti bor" degan bog'lanishni yozib qo'yadi. Bu juft upstream (yuqori oqim) deyiladi. Bir marta -u bilan yuborgach, keyingi safar faqat git push va git pull yetadi: Git qayerga va qaysi branchga ekanini biladi.

Terminalingizda bundan oldin bir necha qator ko'rishingiz mumkin. Bular — yuborish jarayoni:

text
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 374 bytes | 374.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)

Bu bizning boshqa bir push'imizdan olingan, sonlar sizda boshqacha. Endi Git ichkaridan darsini eslang: Git obyektlarni — commit, tree va blob'larni — sanaydi, siqadi va yuboradi. Total 4 — to'rtta obyekt ketdi. delta — Git o'xshash fayllarning faqat farqini yubordi.

Endi GitHub'dagi repo sahifasini yangilang — fayllaringiz va commitlar tarixi o'sha yerda.

3.1 Bog'lanish qayerda yozilgan?

bash
git branch -vv
git log --oneline -3
text
* main 2bed66c [origin/main] Git: .gitattributes qo'sh
2bed66c (HEAD -> main, origin/main) Git: .gitattributes qo'sh
333f3cd Aloqa sahifasi
ad6d144 Bosh sahifa: aloqa havolasi

[origin/main] — main ning upstream'i. Tarixda esa yangi yorliq paydo bo'ldi: origin/main. Hammasi .git/config faylida yozilgan:

text
[remote "origin"]
	url = https://github.com/login/bahor.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
	remote = origin
	merge = refs/heads/main

Birinchi bo'lim — git remote add yozgani. fetch = ... qatori shunday o'qiladi: "GitHub'dagi har bir branchni (refs/heads/*) menda refs/remotes/origin/* ga yoz". Ikkinchi bo'lim — -u yozgani: "main ning jufti — origin dagi main".

4. origin/main — oxirgi ko'rgan holat

HEAD va refs darsida refs/heads/ dagi oddiy branchlarni ko'rgan edingiz. origin/main — boshqa tur: remote-tracking branch (kuzatuvchi branch). U .git/refs/remotes/origin/main da turadi.

U "GitHub'dagi main oxirgi marta qanday edi" degan suratni saqlaydi. Do'konga oxirgi borganingizda vitrinaga qarab olgan rasmni tasavvur qiling. Uyda turib rasmga qarasangiz — o'sha paytdagi holatni ko'rasiz, hozirgisini emas. Rasm faqat siz yana do'konga borganingizda — fetch yoki push qilganingizda — yangilanadi.

Shuning uchun origin/main ga to'g'ridan-to'g'ri commit qilib bo'lmaydi: u siz yozadigan branch emas, GitHub'ning aksi.

bash
git branch -a
text
* main
  remotes/origin/main

-a (all) — lokal branchlar va kuzatuvchi branchlar birga. git branch -r — faqat kuzatuvchilar.

Tekshirib ko'ring: Kecha git push qildingiz. Bugun ertalab Sardor GitHub'ga yangi commit yubordi. Siz hech narsa qilmasdan git log --oneline -1 origin/main yozsangiz, Sardorning commitini ko'rasizmi?

Javob

Yo'q. origin/main — oxirgi push yoki fetch paytidagi surat. Siz undan keyin GitHub bilan gaplashmadingiz, shuning uchun u kechagi holatda. Sardorning commitini ko'rish uchun avval git fetch kerak.

5. git clone — reponi nusxalab olish

Sardor o'z noutbukida ishlay boshlaydi. Unga reponi butun tarixi bilan olish kerak:

bash
cd ~/kurs
git clone https://github.com/login/bahor.git

Terminalda Sardor shuni ko'radi:

text
Cloning into 'bahor'...
remote: Enumerating objects: 35, done.
remote: Counting objects: 100% (35/35), done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 35 (delta 9), reused 32 (delta 6), pack-reused 0 (from 0)
Receiving objects: 100% (35/35), done.
Resolving deltas: 100% (9/9), done.

remote: bilan boshlangan qatorlar — GitHub'ning o'zi yozayotgan xabarlar: u obyektlarni sanab, siqib yubordi. Receiving objects — kompyuter ularni qabul qildi. (Bu chiqish keyinroq, repo'da ko'proq commit bo'lganda olingan.)

git clone to'rt ishni bittada qiladi: yangi papka yaratadi, ichida git init qiladi, origin remote'ini qo'shadi va hamma narsani olib kelib, main ni ochadi. Natijani tekshiramiz:

bash
cd bahor
git remote -v
git branch -a
git log --oneline -3
text
origin	https://github.com/login/bahor.git (fetch)
origin	https://github.com/login/bahor.git (push)
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
2bed66c (HEAD -> main, origin/main, origin/HEAD) Git: .gitattributes qo'sh
333f3cd Aloqa sahifasi
ad6d144 Bosh sahifa: aloqa havolasi

SHA'lar Azizdagi bilan aynan bir xil — bu o'sha commitlar, nusxasi emas (Git ichkaridan). origin/HEAD -> origin/main — "GitHub'dagi asosiy branch — main". Clone'da main allaqachon origin/main ni kuzatadi — -u shart emas.

Ochiq (public) repolarni hech qanday kirishsiz clone qilish mumkin. Yopiq repolarda va har qanday push'da esa GitHub sizni tanishi kerak.

Maslahat: git clone <manzil> boshqa-nom — papka nomini o'zingiz berasiz. Clone'ni har doim repo bo'lmagan papkada qiling (masalan ~/kurs), aks holda repo ichida repo paydo bo'ladi (Birinchi repo darsidagi "Repo noto'g'ri papkada" holati).

6. git fetch — yangiliklarni olib kelish

Sardor menyuga somsa narxini qo'shdi va yubordi. Uning terminalida:

text
To https://github.com/login/bahor.git
   2bed66c..cbfe564  main -> main

2bed66c..cbfe564 — GitHub'dagi main eski commitdan yangisiga surildi.

6.1 git status hali bilmaydi

Aziz o'z kompyuterida:

bash
git status
text
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

"Siz origin/main bilan bir xilsiz" — lekin GitHub'da yangi commit bor! Yolg'onmi? Yo'q: Git o'zining oxirgi suratiga qarab gapiryapti. git status hech qachon internetga chiqmaydi. Bu boshlovchilarning eng ko'p chalkashadigan joyi.

6.2 Fetch

bash
git fetch
git status
text
From https://github.com/login/bahor
   2bed66c..cbfe564  main       -> origin/main
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean

fetch nima qildi: GitHub'dan yangi commitni olib keldi va origin/main ni cbfe564 ga surdi. Sizning main ingizga va fayllaringizga tegmadi. Endi status haqiqatni aytadi: "1 commit orqadasiz va oldinga surilishingiz mumkin (fast-forward)".

Fetch — xavfsiz buyruq: uni istalgancha yozish mumkin.

6.3 Birlashtirishdan oldin ko'rib chiqish

Fetch'dan keyin nima kelganini bemalol ko'rasiz (git log va git diff bilimlari):

bash
git log --oneline main..origin/main
git diff main origin/main
text
cbfe564 (origin/main, origin/HEAD) Menyu: somsa narxini qo'sh
diff --git a/menyu/index.html b/menyu/index.html
index 8441788..ddd0d84 100644
--- a/menyu/index.html
+++ b/menyu/index.html
@@ -1,2 +1,3 @@
 <h1>Menyu</h1>
 <p>Osh — 35 000 so'm</p>
+<p>Somsa — 8 000 so'm</p>

main..origin/main — "origin/main da bor, main da yo'q commitlar". Hammasi joyida — qo'shamiz:

bash
git merge
text
Updating 2bed66c..cbfe564
Fast-forward
 menyu/index.html | 1 +
 1 file changed, 1 insertion(+)

git merge argumentsiz — upstream'ni, ya'ni origin/main ni qo'shadi. Ish faqat siz tomonda edi, shuning uchun fast-forward: main shunchaki oldinga surildi.

gitGraph
  commit id: "333f3cd"
  commit id: "2bed66c"
  commit id: "cbfe564 somsa" tag: "origin/main"

Nimaga qarang: tarix bitta to'g'ri chiziq. Fetch'dan keyin main 2bed66c da, origin/main esa bir qadam oldinda edi. Merge main ni ham o'sha yerga surdi.

7. git pull = fetch + merge

Har safar ikki buyruq yozmaslik uchun git pull bor. Sardor yana manti narxini yubordi. Aziz:

bash
git pull
text
From https://github.com/login/bahor
   cbfe564..b1a0742  main       -> origin/main
Updating cbfe564..b1a0742
Fast-forward
 menyu/index.html | 1 +
 1 file changed, 1 insertion(+)

Chiqishning ikki qismi aniq ko'rinadi: yuqorisi (From ...) — fetch, pastki qismi (Updating ... Fast-forward) — merge.

Buyruq GitHub'dan oladi origin/main Sizning main
git fetch ha yangilanadi o'zgarmaydi
git pull ha yangilanadi birlashtiriladi
git status yo'q o'zgarmaydi o'zgarmaydi

Kundalik ishda — git pull. Avval ko'rib chiqmoqchi bo'lsangiz — git fetch, log/diff, keyin merge.

Bu safar ikkalasi ham fast-forward bo'ldi: Aziz o'z commitini qilmagan edi. Ikki tomon ham commit qilgan bo'lsa-chi? Unda tarix ayriladi va git pull sozlamaga qarab merge commit yaratadi yoki to'xtaydi. Bu — keyingi darsning mavzusi: Ajralgan tarix.

Tekshirib ko'ring: Aziz git fetch qildi, keyin brauzerda sayt faylini ochdi. Sardorning o'zgarishini ko'radimi?

Javob

Yo'q. Fetch ishchi papkaga tegmaydi — faqat origin/main ni yangilaydi. Fayllarda o'zgarish git merge (yoki git pull) dan keyin paydo bo'ladi.

8. Ahead va behind

Endi Aziz o'zi commit qiladi — bosh sahifaga ish vaqtini yozadi:

bash
git status
git branch -vv
text
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
* main b8359cd [origin/main: ahead 1] Bosh sahifa: ish vaqtini qo'sh

Ahead — "oldinda": sizda GitHub'da hali yo'q commit bor. Behind — "orqada": GitHub'da sizda yo'q commit bor. Yuborish:

bash
git push
text
To https://github.com/login/bahor.git
   b1a0742..b8359cd  main -> main

Upstream sozlangani uchun git push ning o'zi yetdi. Branch nima darsida aytilgan [origin/main: ahead 2] yozuvi — aynan shu.

git status yozuvi Ma'nosi Nima qilasiz
up to date Oxirgi suratga ko'ra bir xil Ishonch uchun git fetch
ahead 1 Sizda yuborilmagan commit git push
behind 1 GitHub'da yangi commit git pull
have diverged Ikki tomonda ham yangi commit Ajralgan tarix

9. Yangi branchni yuborish

Aziz bron sahifasi uchun alohida branch ochdi va commit qildi. Yubormoqchi:

bash
git switch -c feature/bron-vaqt
git push
text
fatal: The current branch feature/bron-vaqt has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/bron-vaqt

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

Tarjimasi: "joriy branchning upstream'i yo'q. Uni yuborish va remote'ni upstream qilish uchun: git push --set-upstream origin feature/bron-vaqt". Yangi branch faqat sizda — GitHub'da uning jufti hali yo'q. Pastki qatordagi push.autoSetupRemote sozlamasini Git konfiguratsiyasi darsida ko'rasiz.

bash
git push -u origin feature/bron-vaqt
text
remote: 
remote: Create a pull request for 'feature/bron-vaqt' on GitHub by visiting:
remote:      https://github.com/login/bahor/pull/new/feature/bron-vaqt
remote: 
To https://github.com/login/bahor.git
 * [new branch]      feature/bron-vaqt -> feature/bron-vaqt
branch 'feature/bron-vaqt' set up to track 'origin/feature/bron-vaqt'.

remote: qatorlari — GitHub'dan xabar: "shu branch uchun Pull Request ochish mumkin, mana havola". Pull Request'ni Pull Request darsida o'rganasiz. Hozircha shunchaki: branch GitHub'da.

Hamma bog'lanishlarni bitta joyda ko'rish:

bash
git remote show origin
text
* remote origin
  Fetch URL: https://github.com/login/bahor.git
  Push  URL: https://github.com/login/bahor.git
  HEAD branch: main
  Remote branches:
    feature/bron-vaqt tracked
    main              tracked
  Local branches configured for 'git pull':
    feature/bron-vaqt merges with remote feature/bron-vaqt
    main              merges with remote main
  Local refs configured for 'git push':
    feature/bron-vaqt pushes to feature/bron-vaqt (up to date)
    main              pushes to main              (up to date)

git remote show — remote -v dan farqli, GitHub bilan gaplashib, hozirgi holatni ko'rsatadi.

9.1 Sardor yangi branchni oladi

bash
git fetch
git switch feature/bron-vaqt
text
From https://github.com/login/bahor
   b1a0742..b8359cd  main              -> origin/main
 * [new branch]      feature/bron-vaqt -> origin/feature/bron-vaqt
Switched to a new branch 'feature/bron-vaqt'
branch 'feature/bron-vaqt' set up to track 'origin/feature/bron-vaqt'.

Sardorda bunday lokal branch yo'q edi. git switch buni sezdi: origin/feature/bron-vaqt bor ekan — shu nomli lokal branch yaratdi va uni kuzatadigan qildi.

9.2 Branchni GitHub'dan o'chirish

Ish tugagach, GitHub'dagi branch o'chiriladi:

bash
git push origin --delete feature/bron-vaqt
text
To https://github.com/login/bahor.git
 - [deleted]         feature/bron-vaqt

Sardorning kompyuterida esa origin/feature/bron-vaqt hali turibdi — surat eski. Uni tozalash uchun --prune:

bash
git fetch --prune
git branch -vv
text
From https://github.com/login/bahor
 - [deleted]         (none)     -> origin/feature/bron-vaqt
  feature/bron-vaqt 30d383a [origin/feature/bron-vaqt: gone] Bron: oxirgi bron vaqtini yoz
* main              b1a0742 [origin/main: behind 1] Menyu: manti narxini qo'sh

gone — "upstream'i yo'qolgan". Sardorning lokal branchi o'chmadi — o'zi git branch -d bilan o'chiradi.

10. Taglarni yuborish

Tag va relizlar darsida bilgan edingiz: oddiy git push taglarni yubormaydi. Tagni nomi bilan yuborasiz — bir nechtasini birdan ham:

bash
git push origin v1.0.0 brauzer-tarixi
text
To https://github.com/login/login.github.io.git
 * [new tag]         v1.0.0 -> v1.0.0
 * [new tag]         brauzer-tarixi -> brauzer-tarixi

Bu — portfolio'dan (keyingi bo'lim). push.followTags yoqilgan bo'lsa, annotated taglar commit bilan birga ketadi.

11. Portfolio: brauzerdan yuklangan repo bilan bog'lash

Endi eng muhim qadam. Birinchi deploy darsidan beri login.github.io repongizga fayllarni brauzer orqali yuklab keldingiz. Birinchi repo darsida esa kompyuterda kurs/portfolio reposini ochdingiz. Ikkalasini bog'laymiz — va saytni bir soniya ham buzmaymiz.

11.1 Vaziyat: ikki alohida tarix

GitHub'dagi tarix (har biri — Commit changes tugmasi):

  • Birinchi versiya (04-qism), CSS: 05-qism yakuni, Loyihalar: landing kartasi (06-qism).
  • Fayllar repo ildizida: index.html, assets/, loyihalar/ ...
  • Pages: Deploy from a branch, main, / (root).

Kompyuterdagi tarix:

  • Portfolio: 06-qism oxiridagi holat va 07-qismdagi commitlaringiz, v1.0.0 tagi, tajriba branchi.
  • Sayt fayllari sayt/ papkasida, ildizda esa package.json, .gitignore va sozlamalar.
flowchart LR
  subgraph G["GitHub: main"]
    G1["Birinchi versiya"] --> G2["CSS: 05-qism"] --> G3["landing kartasi"]
  end
  subgraph K["Kompyuter: main"]
    K1["06-qism holati<br/>v1.0.0"] --> K2["eski CSS'ni o'chir"] --> K3[".gitattributes"] --> K4["harflar oralig'i"]
  end

Nimaga qarang: ikki zanjir hech qayerda tutashmaydi — umumiy ota commit yo'q. Mazmun esa bir xil: brauzer tarixi — sayt fayllarining eski nusxalari, ular kompyuterdagi sayt/ da allaqachon bor.

Yechim rejasi:

  1. Remote qo'shib, git fetch — GitHub tarixini ko'rib chiqamiz.
  2. GitHub'da faqat o'sha yerda bo'lgan o'zgarish yo'qligini tekshiramiz.
  3. Eski tarixni tag bilan saqlab qo'yamiz.
  4. Saytni sayt/ dan joylaydigan workflow faylini qo'shamiz.
  5. Pages manbasini GitHub Actions ga o'tkazamiz.
  6. git push --force-with-lease bilan GitHub tarixini lokal tarix bilan almashtiramiz.

Biz bu rejani sinov reposida qadamma-qadam bajardik. Chiqishlarda repo nomi login/login.github.io ga almashtirilgan. Sinovdagi lokal portfolio — qisqartirilgan nusxa: 07-qismdagi o'nlab commit o'rnida uchtasi, ikkitasining nomi ham boshqacharoq (Portfolio: eski CSS nusxasini o'chir, Git: .gitattributes qo'sh). Sizda tarix uzunroq va nomlar Yaxshi commit hamda .gitattributes darslaridagidek bo'ladi.

11.2 Fetch va ko'rib chiqish

bash
cd ~/kurs/portfolio
git remote add origin https://github.com/login/login.github.io.git
git fetch origin
git log --oneline --graph --all
text
From https://github.com/login/login.github.io
 * [new branch]      main       -> origin/main
* 1d10dc4 (HEAD -> main) CSS: sarlavha harflarini kengaytir
* a2b11f9 (tajriba) Git: .gitattributes qo'sh
* f4469c7 Portfolio: eski CSS nusxasini o'chir
* 1a2a65c (tag: v1.0.0) Portfolio: 06-qism oxiridagi holat
* 0b78655 (origin/main, origin/HEAD) Loyihalar: landing kartasi
* a98e690 CSS: 05-qism yakuni
* 06911e7 Birinchi versiya

Ehtiyot bo'ling: chizma bitta chiziqqa o'xshaydi, lekin bu aldamchi. git log ikki zanjirni shunchaki ketma-ket chizdi. Tekshiramiz — ikki branchning umumiy ota commiti bormi?

bash
git merge-base main origin/main
echo $?
text
1

git merge-base hech narsa chiqarmadi va chiqish kodi 1 (exit code) — umumiy ota yo'q. Endi oddiy push'ni sinaymiz:

bash
git push -u origin main
text
To https://github.com/login/login.github.io.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/login/login.github.io.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Tarjimasi: "rad etildi: fast-forward emas". GitHub'dagi main ning commitlari sizning tarixingizda yo'q — oddiy push ularni yo'qotib yuborardi, Git bunga yo'l qo'ymaydi. Maslahat git pull deydi, lekin birlashtirib ko'raylik:

bash
git merge origin/main
text
fatal: refusing to merge unrelated histories

"Bog'liq bo'lmagan tarixlarni birlashtirishdan bosh tortaman." Git to'g'ri qiladi. Majburlab birlashtirish mumkin (--allow-unrelated-histories), lekin natija chalkash bo'ladi: ildizda index.html, assets/ — va yana sayt/index.html, sayt/assets/. Bir saytning ikki nusxasi.

11.3 GitHub'da faqat o'sha yerda nima bor?

Brauzer tarixini tashlab yuborishdan oldin ishonch hosil qilamiz: GitHub'dagi oxirgi holat kompyuterdagi sayt/ da bormi? Ikkala daraxtni solishtiramiz:

bash
git ls-tree --name-only origin/main
git diff --stat origin/main main:sayt
text
404.html
aloqa
assets
favicon.svg
haqimda
index.html
loyihalar
 assets/css/asosiy.css | 1 +
 1 file changed, 1 insertion(+)

main:sayt — "main dagi sayt/ papkasi". Git GitHub ildizini lokal sayt/ bilan solishtirdi. Farq bitta qator — va u sizning 07-qismdagi yangi commitingiz (harflar oralig'i). Demak, GitHub'da faqat o'sha yerda bo'lgan narsa yo'q.

Agar farqda GitHub tomonda yangi narsa chiqsa (masalan, faylni GitHub saytida to'g'ridan-to'g'ri tahrirlagan bo'lsangiz), uni avval kompyuterga ko'chiring:

bash
git show origin/main:loyihalar/index.html > sayt/loyihalar/index.html

git show <commit>:<yo'l> — faylning o'sha commitdagi mazmuni. Keyin uni odatdagidek commit qilasiz.

11.4 Eski tarixni saqlab qo'yish

Brauzer commitlari sizning birinchi qadamlaringiz. Ularni yo'qotmaslik uchun tag qo'yamiz:

bash
git tag brauzer-tarixi origin/main
git tag
text
brauzer-tarixi
v1.0.0

Tag bor ekan, commitlar hech qachon yo'qolmaydi. Uni GitHub'ga ham yuboramiz (yuqoridagi «Taglarni yuborish» bo'limi).

11.5 Workflow fayli: saytni sayt/ dan joylash

Push'dan keyin GitHub'dagi main ning ildizida index.html bo'lmaydi — u sayt/ ichida. Pages esa hozir ildizdan joylaydi. Shuning uchun Pages'ga yangi yo'l kerak: GitHub Actions — har push'dan keyin GitHub'ning o'zida ishlaydigan avtomatik vazifa. Unga "sayt/ papkasini olib, saytga joyla" deymiz.

Hozir bu faylni ko'chirib qo'yasiz — har qatorini GitHub Actions va Pages va Actions darslarida ochamiz. Bu — boshlang'ich, minimal versiya: u saytni darhol joylaydi. Pages va Actions darsida unga "avval tekshir" ishini qo'shib, 07-qismning yakuniy pages.yml iga aylantiramiz. Fayl yo'li aniq shunday bo'lishi kerak: .github/workflows/pages.yml.

yaml
name: Pages

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/configure-pages@v6
      - uses: actions/upload-pages-artifact@v5
        with:
          path: sayt
      - id: deployment
        uses: actions/deploy-pages@v5

Hozircha ikki qatorni tushunsangiz yetarli: branches: [main] — "main ga push bo'lganda ishga tush", path: sayt — "saytga faqat sayt/ papkasini yukla". Shu qator tufayli package.json va boshqa sozlama fayllari internetga chiqmaydi (Birinchi deploy darsidagi «Hujumchi nigohi»). Bu fayl tuzilmasi docs.github.com dagi rasmiy namunaga asoslangan; amallar versiyalari — 2026-yil oktabr holati.

bash
mkdir -p .github/workflows
code .github/workflows/pages.yml
git add .github/workflows/pages.yml
git commit -m "Deploy: sayt/ ni Pages'ga yuklaydigan workflow qo'sh"
text
[main 61ed156] Deploy: sayt/ ni Pages'ga yuklaydigan workflow qo'sh
 1 file changed, 30 insertions(+)
 create mode 100644 .github/workflows/pages.yml

11.6 Pages manbasini almashtirish

Push'dan oldin GitHub'da (docs.github.com, 2026-yil sentyabr holati):

  1. login.github.io repo → Settings.
  2. Chap menyuning "Code, planning, and automation" bo'limida → Pages.
  3. "Build and deployment" → Source → GitHub Actions.

GitHub bir nechta tayyor workflow taklif qiladi — tanlamang, sizning faylingiz tayyor.

Nega oldin? Agar avval push qilsangiz, Pages hali ham "ildizdan joyla" rejimida bo'ladi — ildizda esa index.html yo'q. Sayt buzilardi. Manba almashgach esa eski sayt yangi deploy kelguncha ishlayveradi: biz sinov reposida manbani almashtirib, saytni tekshirdik — eski sahifa va eski CSS ochilib turdi.

11.7 Majburiy, lekin xavfsiz push

Endi GitHub tarixini lokal tarix bilan almashtiramiz. Oddiy push rad etildi, shuning uchun majburiy push kerak. Lekin oddiy --force emas — --force-with-lease:

bash
git push --force-with-lease -u origin main
text
To https://github.com/login/login.github.io.git
 + 0b78655...61ed156 main -> main (forced update)
branch 'main' set up to track 'origin/main'.

+ va (forced update) — tarix almashtirildi: GitHub'dagi main endi 61ed156 da. --force-with-lease (ijara bilan majburlash) — "GitHub'dagi main hali ham men fetch da ko'rgan 0b78655 da bo'lsa — almashtir, aks holda to'xta". Ya'ni siz ko'rib chiqqan narsanigina ustidan yozasiz. Uning ishlashini va oddiy --force nega xavfli ekanini keyingi darsda jonli ko'rasiz.

Keyin taglar (v1.0.0, brauzer-tarixi) — «Taglarni yuborish» bo'limidagi buyruq. Tekshiruv:

bash
git status
git log --oneline --graph -3
text
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
* 61ed156 (HEAD -> main, origin/main, origin/HEAD) Deploy: sayt/ ni Pages'ga yuklaydigan workflow qo'sh
* 1d10dc4 CSS: sarlavha harflarini kengaytir
* a2b11f9 (tajriba) Git: .gitattributes qo'sh

11.8 Sayt yangilandimi?

Push workflow'ni ishga tushiradi. Repo sahifasidagi Actions bo'limida "Pages" nomli ish paydo bo'ladi. Sariq — ketyapti, yashil — tayyor, qizil — xato (Birinchi deploy darsida shu bo'limni ko'rgan edingiz).

Biz ishni sinov reposida kuzatdik. Brauzerdagi Actions sahifasi ko'rsatadigan ma'lumotni terminalda gh buyrug'i bilan ham olish mumkin — uni keyinroq o'rganasiz, hozir faqat natijaga qarang:

text
✓ main Pages · 36818378196
Triggered via workflow_dispatch less than a minute ago

JOBS
✓ deploy in 16s (ID 110228357187)
  ✓ Set up job
  ✓ Run actions/checkout@v7
  ✓ Run actions/configure-pages@v6
  ✓ Run actions/upload-pages-artifact@v5
  ✓ Run actions/deploy-pages@v5
  ✓ Post Run actions/checkout@v7
  ✓ Complete job

ARTIFACTS
github-pages

Ikki chiqishni (gh run view va gh run watch) birlashtirdik, ishni bajargan GitHub kompyuteri (runner) haqidagi bitta xizmat izohini tashlab ketdik. ✓ — yashil belgi: workflow'dagi to'rtta qadam ketma-ket bajarildi. github-pages — sayt/ dan yig'ilgan arxiv, Pages aynan shuni joyladi. Biz bu ishni Actions sahifasidagi tugma bilan qayta ishga tushirgan edik (workflow_dispatch). Sizda push'dan keyin Triggered via push yoziladi.

Keyin saytni tekshirdik: bosh sahifa 200 bilan ochildi, asosiy.css da yangi qator — h1 { letter-spacing: 0.05em; } — paydo bo'ldi. package.json, README.md va sayt/index.html manzillari esa 404 qaytardi.

Bir-ikki daqiqadan keyin https://login.github.io ni Ctrl + Shift + R bilan yangilang. Tekshiruv ro'yxati:

  • Bosh sahifa ochiladi, CSS ishlaydi, havolalar to'g'ri.
  • https://login.github.io/package.json — 404. Sozlama fayllari internetda yo'q.
  • https://login.github.io/sayt/ — ham 404: sayt/ saytning ildizi bo'ldi.

Workflow xato bersa-chi? Sinovdagi push'lardan birida aynan shunday bo'ldi: ish akkaunt sozlamasi sababli umuman boshlanmadi. Shunda ham sayt ishlab turdi — Pages oxirgi muvaffaqiyatli joylangan versiyani ko'rsatishda davom etdi. Xatoni Actions bo'limidagi ish sahifasida o'qiysiz; tuzatib, yana push qilasiz.

Tekshirib ko'ring: Nega git pull --allow-unrelated-histories bilan birlashtirish o'rniga GitHub tarixini almashtirdik? Biz nimani yo'qotmaganimizga qanday ishonch hosil qildik?

Javob

Birlashtirish ildizda va sayt/ da saytning ikki nusxasini qoldirardi. Brauzer tarixi — sayt/ fayllarining eski holati, yangi ma'lumot emas. Yo'qotmaganimizni uch narsa kafolatlaydi:

  • git diff origin/main main:sayt — GitHub'da faqat o'sha yerda bo'lgan o'zgarish yo'q.
  • brauzer-tarixi tagi — eski commitlar saqlanib qoldi.
  • --force-with-lease — biz ko'rmagan yangi commit bo'lsa, push to'xtardi.

12. Remote'ni boshqarish

bash
git remote set-url origin git@github.com:login/bahor.git
git remote -v
text
origin	git@github.com:login/bahor.git (fetch)
origin	git@github.com:login/bahor.git (push)

set-url — manzilni almashtiradi: masalan HTTPS'dan SSH'ga (SSH kalit darsi). Boshqa buyruqlar:

Buyruq Nima qiladi
git remote rename origin eski Remote nomini o'zgartiradi
git remote remove eski Bog'lanishni o'chiradi (GitHub'dagi repo o'chmaydi)
git remote show origin Batafsil holat

Bitta repoda bir nechta remote bo'lishi mumkin. Masalan, boshqaning loyihasiga hissa qo'shganda origin — sizning nusxangiz, upstream — asl loyiha. Buni Fork va upstream darsida ko'rasiz.

13. Ko'p uchraydigan xatolar

13.1 remote origin already exists

text
error: remote origin already exists.

origin allaqachon qo'shilgan. Ko'pincha clone qilingan repoda yoki remote add ni ikkinchi marta yozganda chiqadi. Manzilni almashtirmoqchi bo'lsangiz — git remote set-url origin <yangi>.

13.2 Repository not found

Repo nomida xato bilan sinadik:

text
remote: Repository not found.
fatal: repository 'https://github.com/login/bahr.git/' not found

Sabablar: nomda xato (bahr), repo yopiq va siz boshqa akkaunt bilan kirgansiz, yoki repo hali yaratilmagan. Avval manzilni brauzerda oching.

13.3 rejected ... (fetch first)

Push'dan oldin GitHub'da yangi commit paydo bo'lgan. Avval git pull, keyin push. Ikki tomonda ham commit bo'lsa — Ajralgan tarix.

13.4 "Up to date" deydi, lekin GitHub'da yangi commit bor

git status internetga chiqmaydi. Avval git fetch.

13.5 Birinchi push'dan oldin GitHub'da README yaratilgan

Add README yoqilgan bo'lsa, birinchi push rad etiladi — portfolio holatining kichik nusxasi. Yechim o'sha: git fetch, README'ni kompyuterga ko'chirish (git show origin/main:README.md > README.md), commit va git push --force-with-lease -u origin main.

14. Mashqlar

1-mashq (oson): Qaysi buyruq?

  1. GitHub'dagi yangiliklarni ko'rmoqchisiz, lekin fayllaringizga hali tegmasin.
  2. Hamkasbingiz yuborgan reponi birinchi marta kompyuteringizga olmoqchisiz.
  3. Yangi feature/aloqa-xarita branchini birinchi marta GitHub'ga yubormoqchisiz.
  4. GitHub'dagi yangiliklarni olib, darhol o'z branchingizga qo'shmoqchisiz.
Yechim
  1. git fetch — faqat origin/... yangilanadi.
  2. git clone <manzil>.
  3. git push -u origin feature/aloqa-xarita — -u upstream'ni sozlaydi.
  4. git pull — fetch + merge.

2-mashq (o'rta): Bo'sh joylarni to'ldiring

Aziz yangi choyxona papkasini GitHub'dagi bo'sh login/choyxona repoga bog'lab yubormoqda:

bash
cd ~/kurs/choyxona
git remote  origin https://github.com/login/choyxona.git
git remote 
git push  origin main

Keyin git status Your branch is of 'origin/main' by 1 commit. dedi. Qaysi buyruq kerak: git .

Ishora: «Remote qo'shish», «Birinchi push» va «Ahead va behind» bo'limlari.

Yechim
bash
git remote add origin https://github.com/login/choyxona.git
git remote -v
git push -u origin main
git push

ahead — sizda yuborilmagan commit bor, shuning uchun git push. -u tufayli remote va branch nomini yozish shart emas.

3-mashq (qiyin): Chiqishni o'qing

Sardor ertalab shunday yozdi va natija oldi:

text
$ git status
On branch main
Your branch is up to date with 'origin/main'.
$ git fetch
From https://github.com/login/bahor
   b8359cd..4c1e2a0  main       -> origin/main
$ git branch -vv
* main b8359cd [origin/main: behind 2] Bosh sahifa: ish vaqtini qo'sh
  1. Nega birinchi git status "up to date" dedi?
  2. b8359cd..4c1e2a0 nimani bildiradi?
  3. Sardorning fayllari fetch dan keyin o'zgardimi?
  4. Qaysi bitta buyruq bilan uni yangilaydi va natija qanday bo'ladi?

Ishora: «Status hali bilmaydi», «Fetch» va «pull = fetch + merge» bo'limlari.

Yechim
  1. status oxirgi suratga — eski origin/main ga — qaradi. GitHub bilan gaplashmadi.
  2. GitHub'dagi main b8359cd dan 4c1e2a0 ga surilgan, oralig'ida 2 ta yangi commit.
  3. Yo'q. Fetch faqat origin/main ni yangiladi.
  4. git pull — Sardorning o'z commiti yo'q, shuning uchun Fast-forward bo'ladi va main 4c1e2a0 ga suriladi. (Yoki git merge — fetch allaqachon qilingan.)

4-mashq: Portfolio qadami — portfolio va mashqlar GitHub'da

A. Portfolio. «Portfolio: brauzerdan yuklangan repo bilan bog'lash» bo'limini o'z kurs/portfolio reposingizda qadamma-qadam bajaring. Tekshiruv ro'yxati:

  1. git merge-base main origin/main hech narsa chiqarmaydi (ikki alohida tarix).
  2. git diff --stat origin/main main:sayt da faqat 07-qismdagi o'z o'zgarishlaringiz.
  3. brauzer-tarixi va v1.0.0 taglari GitHub'da.
  4. Pages manbasi — GitHub Actions, push'dan oldin almashtirilgan.
  5. Actions'dagi "Pages" ishi yashil, https://login.github.io ochiladi, /package.json — 404.
  6. git status — up to date with 'origin/main'.

B. mashqlar repo. GitHub'da bo'sh mashqlar repo yarating (README'siz) va kurs/mashqlar ni ulang. Bu darsning javoblarini 07/26-remote/javoblar.md ga yozing va yuboring. Commit: 07/26: remote mashqlari javoblarini qo'sh.

C. landing (ixtiyoriy). landing repongiz ham brauzer orqali yuklangan. Lokal landing repo bo'lsa — A qismdagi yo'l bilan; bo'lmasa — avval git clone, keyin fayllaringizni shu papkaga ko'chirib commit qiling.

Yechim

A — bo'limdagi buyruqlar. Qisqa ro'yxat:

bash
cd ~/kurs/portfolio
git remote add origin https://github.com/login/login.github.io.git
git fetch origin
git merge-base main origin/main
git diff --stat origin/main main:sayt
git tag brauzer-tarixi origin/main
mkdir -p .github/workflows
code .github/workflows/pages.yml
git add .github/workflows/pages.yml
git commit -m "Deploy: sayt/ ni Pages'ga yuklaydigan workflow qo'sh"
# GitHub: Settings → Pages → Source → GitHub Actions
git push --force-with-lease -u origin main
git push origin v1.0.0 brauzer-tarixi
git status

tajriba branchini ham yuborishingiz mumkin: git push -u origin tajriba. U saytga ta'sir qilmaydi — workflow faqat main da ishlaydi.

B — oddiy holat, majburiy push kerak emas: GitHub'dagi repo bo'sh.

bash
cd ~/kurs/mashqlar
git remote add origin https://github.com/login/mashqlar.git
mkdir -p 07/26-remote
code 07/26-remote/javoblar.md
git add 07/26-remote
git commit -m "07/26: remote mashqlari javoblarini qo'sh"
git push -u origin main

Birinchi push'da * [new branch] main -> main va set up to track 'origin/main' chiqadi. Bundan keyin har dars mashqlarini commit qilib, git push qilasiz.

C — clone yo'li: git clone https://github.com/login/landing.git. Clone'da fayllar ildizda bo'ladi — workflow kerak emas, Pages "Deploy from a branch" da qolishi mumkin. Lokal repo bo'lsa (fayllar sayt/ ichida) — A yo'li, workflow'dagi path ham shunga mos.

15. Real ishda

  • Har kuni: ertalab git pull, kun davomida commit, kun oxirida git push. GitHub — kompyuteringiz yo'qolsa ham saqlanib qoladigan zaxira.
  • Jamoada main ga to'g'ridan-to'g'ri push qilinmaydi: har ish o'z branchida yuboriladi va Pull Request orqali qo'shiladi.
  • Birinchi ish kuni "repo'ni clone qiling" topshirig'idan boshlanadi. VS Code tugmalari ham ichida shu fetch/pull/push ni ishlatadi.
  • Intervyuda: "git fetch va git pull farqi?" — eng ko'p beriladigan Git savollaridan biri. Javob: fetch faqat olib keladi va origin/main ni yangilaydi, pull esa yana birlashtiradi.

Xulosa

  • Remote — repo'ning boshqa joydagi nusxasi; asosiysi origin. git remote add, -v, set-url.
  • git push -u origin main — birinchi yuborish va upstream; keyin faqat git push/git pull.
  • origin/main — GitHub'ning oxirgi surati; faqat fetch, pull, push da yangilanadi.
  • fetch — olib keladi, fayllarga tegmaydi; pull — fetch + merge; status internetga chiqmaydi.
  • ahead — push qiling, behind — pull qiling; yangi branch — push -u; taglar — alohida.
  • Brauzerdan yuklangan portfolio: fetch → tekshirish → tag → workflow → Pages: GitHub Actions → --force-with-lease.

Keyingi dars: Ajralgan tarix: pull --rebase va force-with-lease — ikki kishi bir vaqtda commit qilganda nima bo'ladi, "rejected" xatosini qanday xavfsiz yechish va nega --force xavfli.

Manbalar

  • Git hujjati: "git-remote", "git-push", "git-fetch", "git-pull", "git-clone" — git-scm.com/docs
  • Pro Git kitobi: "Working with Remotes", "Remote Branches" — git-scm.com/book
  • GitHub Docs: "About remote repositories", "Managing remote repositories", "Pushing commits to a remote repository", "Creating a new repository" — docs.github.com
  • GitHub Docs: "Configuring a publishing source for your GitHub Pages site", "Using custom workflows with GitHub Pages" — docs.github.com/pages
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Git remote: clone, fetch, pull va push — repo'ni GitHub bilan bog'lash — IlmHamroh