IlmHamroh
JavaScript Full-stack/7-qism. Git va GitHub asoslari27/36-dars22 daqiqa
Mundarija (38)

Git push rejected: ajralgan tarix, git pull --rebase va --force-with-lease

Qisqacha: ! [rejected] ... (non-fast-forward) — GitHub'da sizda yo'q commit bor, oddiy push uni o'chirib yuborardi. Yechim — avval birlashtirish: git pull --rebase sizning yuborilmagan commitlaringizni GitHub'dagilar ustiga qayta teradi va tarix to'g'ri chiziq bo'lib qoladi. Doimiy qilish uchun git config --global pull.rebase true. Tarixni ataylab qayta yozgan bo'lsangiz (amend, rebase), --force emas, --force-with-lease ishlating: u siz ko'rmagan boshqa odamning commitini o'chirib yubormaydi.

Bu darsda

  • rejected (fetch first) va rejected (non-fast-forward) xatolarini o'qib, sababini tushuntira olasiz.
  • Ajralgan tarixni uch yo'l bilan — merge, rebase, ff-only — birlashtirasiz va farqini bilasiz.
  • pull.rebase va pull.ff sozlamalarini tanlab, qo'ya olasiz.
  • git pull --rebase paytidagi conflictni yechasiz.
  • --force nega xavfli ekanini real misolda ko'rasiz va --force-with-lease bilan xavfsiz yuborasiz.
  • git branch -u bilan upstream'ni sozlaysiz.

Oldin bilishingiz kerak: Remote: clone, fetch, pull, push, Rebase: tarixni chiziqlash va oltin qoida, Merge: fast-forward va uch tomonlama birlashtirish.

1. Nega bu kerak?

Oldingi darsda hamma narsa silliq o'tdi: Sardor yubordi, Aziz git pull qildi — fast-forward. Chunki ular navbat bilan ishladi. Haqiqiy jamoada esa ikki kishi bir vaqtda commit qiladi.

Dushanba, soat 10:00. Sardor menyuga lag'mon narxini qo'shib, yubordi. Besh daqiqadan keyin Aziz bosh sahifaga ish vaqtini yozdi va u ham yubormoqchi. Endi bitta main ning ikki xil davomi bor — tarix ayrildi.

Bu darsda ayrilgan tarixni qanday birlashtirishni va tarixni qayta yozish kerak bo'lganda boshqalarning ishini qanday buzmaslikni o'rganamiz. Oldingi darslarda — amend, reset va rebase da — "yuborilgan commitga tegmang, bu holatni keyinroq ko'ramiz" degan edik — o'sha "keyinroq" keldi.

Biz darsdagi hamma buyruqni vaqtinchalik sinov reposida, ikki alohida nusxada (Aziz va Sardor) ishga tushirdik. Chiqishlarda repo nomi login/bahor ga almashtirilgan. Sinov reposidagi «Bahor» tarixi qisqa: Birinchi repo darsining dastlabki commitlari, qisqaroq nomlar bilan (Menyu: osh narxi, Aloqa sahifasi). Sizda tarix uzunroq, nomlar va SHA'lar boshqacha — bu darsdagi xabarlar va ularning ma'nosi esa aynan shunday.

2. "Rejected" — GitHub nega rad etadi?

2.1 fetch first

Aziz o'z commitini yubormoqchi:

bash
git push
text
To https://github.com/login/bahor.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/login/bahor.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Tarjimasi: "Rad etildi (avval fetch qiling). Yangilanish rad etildi, chunki remote'da sizda yo'q ish bor. Odatda buning sababi — boshqa repo shu branchga yuborgan. Remote'dagi o'zgarishlarni qo'shmoqchi bo'lsangiz, qayta yuborishdan oldin git pull qiling."

fetch first — Git GitHub'dagi yangi commitni hatto tanimaydi ham: u Azizning kompyuterida yo'q.

2.2 non-fast-forward

Aziz fetch qiladi va yana urinadi:

bash
git fetch
git push
text
From https://github.com/login/bahor
   c850598..0e3a9e1  main       -> origin/main
To https://github.com/login/bahor.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/login/bahor.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.

Endi sabab boshqacha yozilgan: "joriy branchingizning uchi remote'dagi juftidan orqada". Git endi Sardorning commitini taniydi va aniq aytadi: bu yuborish fast-forward emas.

Nima degani? Push faqat GitHub'dagi main ni oldinga surishi mumkin — xuddi fast-forward merge kabi. GitHub'dagi main ning oxirgi commiti sizning tarixingizda bo'lishi kerak. Bu yerda esa u yo'q: Azizning commiti Sardorning commiti ustida emas, yonida turibdi. Oddiy push Sardorning commitini GitHub'dan o'chirib yuborardi — Git bunga yo'l qo'ymaydi.

2.3 Holatni ko'rish

bash
git status
git log --oneline --graph --all -5
text
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" if you want to integrate the remote branch with yours)

nothing to commit, working tree clean
* ee392b2 (HEAD -> main) Bosh sahifa: ish vaqtini qo'sh
| * 0e3a9e1 (origin/main, origin/HEAD) Menyu: lag'mon narxini qo'sh
|/  
* c850598 Git: .gitattributes qo'sh
* 5221077 Aloqa sahifasi
* 7bb2607 Menyu: osh narxi

"Branchingiz va origin/main ayrilgan: mos ravishda 1 va 1 ta farqli commit." Birinchi son — sizda bor, GitHub'da yo'q; ikkinchisi — aksincha.

gitGraph
  commit id: "c850598"
  branch origin/main
  commit id: "0e3a9e1 lag'mon"
  checkout main
  commit id: "ee392b2 ish vaqti"

Nimaga qarang: ikkala commit ham c850598 dan o'sib chiqqan. Birini ikkinchisiga "ulash" kerak — buning uch yo'li bor.

Tekshirib ko'ring: git status have 3 and 0 different commits each desa-chi? Bunday yozuv chiqmaydi — nega? Uning o'rniga nima chiqadi?

Javob

Ikkinchi son 0 bo'lsa, GitHub'da sizda yo'q commit yo'q — tarix ayrilmagan, siz shunchaki oldindasiz. Status Your branch is ahead of 'origin/main' by 3 commits. deydi va oddiy git push ishlaydi.

3. Birlashtirishning uch yo'li

3.1 Sozlamasiz git pull nima qiladi?

Avval qaysi sozlama borligini ko'ramiz:

bash
git config --show-scope --get-all pull.rebase
text
system	false

Git'ni o'rnatish darsidagi jadvalni eslang: Git for Windows o'rnatuvchisi system faylga pull.rebase=false yozgan. Shuning uchun Windows'da git pull merge qiladi. macOS va Linux'da bu sozlama odatda yo'q. U yerda Git to'xtaydi va tanlashni so'raydi. Buni system faylni o'chirib ko'rib sinadik:

text
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint:   git config pull.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

Tarjimasi: "Branchlaringiz ayrilgan, ularni qanday yarashtirishni ko'rsating. Keyingi pull'dan oldin quyidagilardan birini bajaring: merge, rebase yoki faqat fast-forward." Git uch yo'lni aniq sanab berdi. Har birini ko'ramiz.

3.2 Merge (--no-rebase)

Windows'dagi odatiy git pull:

bash
git pull
text
Merge made by the 'ort' strategy.
 menyu/index.html | 1 +
 1 file changed, 1 insertion(+)

Merge commit yaratildi. Undan oldin VS Code xabar oynasini ochadi (core.editor) — tayyor xabarni saqlab, yopasiz. Tarix:

text
*   4bf0a00 (HEAD -> main) Merge branch 'main' of https://github.com/login/bahor
|\  
| * 0e3a9e1 (origin/main, origin/HEAD) Menyu: lag'mon narxini qo'sh
* | ee392b2 Bosh sahifa: ish vaqtini qo'sh
|/  
* c850598 Git: .gitattributes qo'sh

Ishladi, lekin Merge branch 'main' of https://... degan commit hech qanday foydali ma'lumot bermaydi. Kuniga besh marta pull qilsangiz — tarixda besh shunday commit. Ko'p jamoalar buni "shovqin" deb hisoblaydi.

(Sinovdan keyin bu merge'ni git reset --hard HEAD~1 bilan bekor qildik — Reset darsidagi usul, chunki u hali yuborilmagan edi.)

3.3 Faqat fast-forward (--ff-only)

bash
git pull --ff-only
text
hint: Diverging branches can't be fast-forwarded, you need to either:
hint:
hint: 	git merge --no-ff
hint:
hint: or:
hint:
hint: 	git rebase
hint:
hint: Disable this message with "git config set advice.diverging false"
fatal: Not possible to fast-forward, aborting.

"Fast-forward mumkin emas, to'xtatildi." --ff-only hech narsani birlashtirmaydi: tarix ayrilgan bo'lsa — to'xtaydi va qaror sizga qoladi. Bu "ehtiyot rejimi": siz bilmasdan merge commit paydo bo'lmaydi (Merge darsida --ff-only haqida aytgan edik).

3.4 Rebase (--rebase)

bash
git pull --rebase
git log --oneline --graph -4
text
Successfully rebased and updated refs/heads/main.
* 1ef64f4 (HEAD -> main) Bosh sahifa: ish vaqtini qo'sh
* 0e3a9e1 (origin/main, origin/HEAD) Menyu: lag'mon narxini qo'sh
* c850598 Git: .gitattributes qo'sh
* 5221077 Aloqa sahifasi

Bu safar merge commit yo'q. git pull --rebase avval fetch qildi, keyin Azizning commitini Sardorning commiti ustiga qayta terdi — Rebase darsidagidek. Commit yangi SHA oldi (ee392b2 → 1ef64f4), tarix — to'g'ri chiziq. Endi bu fast-forward:

bash
git push
text
To https://github.com/login/bahor.git
   0e3a9e1..1ef64f4  main -> main

Oltin qoida buzilmadimi? Yo'q. Qayta yozilgan commit — ee392b2 — hali hech kimga yuborilmagan edi. Rebase faqat sizning yuborilmagan commitlaringizga tegadi, GitHub'dagilari o'zgarmaydi.

Yo'l Buyruq Tarix Qachon
Merge git pull --no-rebase Ayrilish + merge commit Jamoa shunday kelishgan bo'lsa
Rebase git pull --rebase To'g'ri chiziq Ko'p jamoalarda odatiy
Faqat FF git pull --ff-only Ayrilsa — to'xtaydi Ehtiyot rejimi

Tekshirib ko'ring: Nega git pull --rebase dan keyin Azizning commiti boshqa SHA oldi, Sardorniki esa o'zgarmadi?

Javob

SHA commitning mazmuni va ota commitidan hisoblanadi (Git ichkaridan). Azizning commiti endi boshqa otaga — Sardorning commitiga — ulandi, shuning uchun yangi SHA. Sardorning commiti esa GitHub'dan qanday kelgan bo'lsa, shunday qoldi: rebase faqat lokal, yuborilmagan commitlarni ko'chiradi.

4. Doimiy sozlama: pull.rebase

Har safar --rebase yozmaslik uchun Rebase darsida va'da qilingan sozlamani qo'yamiz:

bash
git config --global pull.rebase true
git config --show-scope --get-all pull.rebase
git config --get pull.rebase
text
system	false
global	true
true

Ikki qiymat bor: system'da false, global'da true. Qaysi biri ishlaydi? Git'ni o'rnatish darsidagi qoida: yaqinroq daraja ustun. git config --get buni tasdiqlaydi — natija true. Endi oddiy git pull rebase qiladi.

Muqobili — git config --global pull.ff only: hamma pull faqat fast-forward, ayrilsa — o'zingiz hal qilasiz. Kursda biz pull.rebase true ni tavsiya qilamiz — u eng ko'p tarqalgan.

4.1 Yarim ish bilan pull

Rebase toza ishchi papka talab qiladi. Commit qilinmagan o'zgarish bo'lsa:

text
error: cannot pull with rebase: You have unstaged changes.
error: Please commit or stash them.

"Rebase bilan pull qilib bo'lmaydi: commit qilinmagan o'zgarishlar bor. Ularni commit yoki stash qiling." Stash darsidagi yo'l — git stash, git pull, git stash pop. Buni bitta flag qiladi: git pull --rebase --autostash — Git o'zgarishlarni vaqtincha javonga qo'yadi va pull'dan keyin qaytaradi. Doimiy qilish: git config --global rebase.autoStash true.

5. git pull --rebase paytida conflict

Ikkalasi bitta qatorni o'zgartirsa nima bo'ladi? Sardor ish vaqtini 8:00–23:00 qildi va yubordi. Aziz esa o'sha qatorga "har kuni" so'zini qo'shdi. Aziz pull qiladi (endi pull.rebase true):

bash
git pull
text
From https://github.com/login/bahor
   1ef64f4..9a65906  main       -> origin/main
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
error: could not apply a8549ec... Bosh sahifa: "har kuni" so'zini qo'sh
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Could not apply a8549ec... # Bosh sahifa: "har kuni" so'zini qo'sh

Tanish manzara — Conflictlarni yechish va Rebase darslaridagidek. (Bir lahzaga Rebasing (1/1) yozuvi ham chiqadi — rebase jarayoni hisoblagichi, keyingi qator uni bosib ketadi.) Faylda:

text
<h1>Bahor choyxonasi</h1>
<a href="aloqa/">Aloqa</a>
<<<<<<< HEAD
<p>Ish vaqti: 8:00–23:00</p>
=======
<p>Ish vaqti: har kuni 7:00–23:00</p>
>>>>>>> a8549ec (Bosh sahifa: "har kuni" so'zini qo'sh)

Diqqat: rebase'da HEAD — GitHub'dan kelgan versiya (Sardorniki), pastdagi — siz qayta terayotgan commit. Merge'dagidan teskari tuyuladi, chunki rebase sizning commitingizni boshqaning tarixi ustiga qo'yyapti.

Ikkalasini birlashtiramiz — Sardorning vaqti va Azizning so'zi:

text
<p>Ish vaqti: har kuni 8:00–23:00</p>
bash
git add index.html
git rebase --continue
git push
text
[detached HEAD f42cff1] Bosh sahifa: "har kuni" so'zini qo'sh
 1 file changed, 1 insertion(+), 1 deletion(-)
Successfully rebased and updated refs/heads/main.
To https://github.com/login/bahor.git
   9a65906..f42cff1  main -> main

--continue paytida commit xabarini tasdiqlash uchun muharrir ochiladi — saqlab, yopasiz. Adashib ketsangiz — git rebase --abort: hammasi pull'dan oldingi holatga qaytadi.

6. Yuborilgan commitni o'zgartirsangiz

Endi boshqa vaziyat. Aziz feature/menyu-chegirma branchida commit qilib, uni yubordi. Keyin xabarni yaxshiladi — amend bilan:

bash
git commit --amend -m "Menyu: dushanbalik chegirmani qo'sh"
git status
text
[feature/menyu-chegirma e5e5044] Menyu: dushanbalik chegirmani qo'sh
 Date: Thu Oct 22 09:00:00 2026 +0500
 1 file changed, 1 insertion(+)
On branch feature/menyu-chegirma
Your branch and 'origin/feature/menyu-chegirma' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" if you want to integrate the remote branch with yours)

nothing to commit, working tree clean

Amend eski commitni almashtirdi — yangi SHA. GitHub'da esa eskisi turibdi. Tarix ayrildi, oddiy push rad etiladi (non-fast-forward). Bu safar git pull ham yechim emas: u eski va yangi commitni birlashtirib, chalkash tarix yasaydi (Rebase darsidagi dublikat commitlar).

Aziz aynan almashtirmoqchi. Buning uchun majburiy push kerak. Lekin qaysi biri?

7. --force nega xavfli: real voqea

Aziz bilmagan narsa: shu orada Sardor ham shu branchga commit qo'shib, yubordi:

text
To https://github.com/login/bahor.git
   a1c2e75..506c0c4  feature/menyu-chegirma -> feature/menyu-chegirma

Avval Aziz to'g'ri buyruqni sinaydi:

bash
git push --force-with-lease
text
To https://github.com/login/bahor.git
 ! [rejected]        feature/menyu-chegirma -> feature/menyu-chegirma (stale info)
error: failed to push some refs to 'https://github.com/login/bahor.git'

"Rad etildi (eskirgan ma'lumot)." Git aytyapti: "siz oxirgi ko'rgan holat (a1c2e75) va hozirgi GitHub (506c0c4) farq qiladi — kimdir yangi narsa yuborgan". Push to'xtadi. Aziz buni tushunmadi va "kuchliroq" buyruqni yozdi:

bash
git push --force
text
To https://github.com/login/bahor.git
 + 506c0c4...e5e5044 feature/menyu-chegirma -> feature/menyu-chegirma (forced update)

O'tdi. GitHub'dagi branch endi Azizning e5e5044 ida. Sardorning 506c0c4 commiti GitHub'dan g'oyib bo'ldi. Sardor fetch qiladi:

text
From https://github.com/login/bahor
 + 506c0c4...e5e5044 feature/menyu-chegirma -> origin/feature/menyu-chegirma  (forced update)
On branch feature/menyu-chegirma
Your branch and 'origin/feature/menyu-chegirma' have diverged,
and have 2 and 1 different commits each, respectively.

(forced update) — "majburan yangilandi": kimdir tarixni qayta yozgan. Bu yozuvni ko'rsangiz — to'xtang va hamkasbingizdan so'rang.

7.1 Tuzoq ichidagi tuzoq

Sardor odatdagidek git pull --rebase qildi:

text
Successfully rebased and updated refs/heads/feature/menyu-chegirma.
e5e5044 (HEAD -> feature/menyu-chegirma, origin/feature/menyu-chegirma) Menyu: dushanbalik chegirmani qo'sh
f42cff1 (origin/main, origin/HEAD) Bosh sahifa: "har kuni" so'zini qo'sh
9a65906 (main) Bosh sahifa: ochilish vaqtini 8:00 qil

Birinchi qator — rebase natijasi, qolgan uchtasi — git log --oneline -3. Sardorning "chegirma havolasi" commiti endi uning o'zida ham yo'q! Sababi: pull --rebase eslab qolgan edi — bu commit avval GitHub'da bor edi, keyin u yerdan olib tashlandi. Git "demak, ataylab o'chirilgan" deb hisobladi va uni qayta termadi. Majburiy push zarari shunday tarqaladi.

Vahima kerak emas: commit yo'qolmagan. Reflog uni eslaydi:

bash
git reflog -4
text
e5e5044 (HEAD -> feature/menyu-chegirma, origin/feature/menyu-chegirma) HEAD@{0}: pull --rebase (finish): returning to refs/heads/feature/menyu-chegirma
e5e5044 (HEAD -> feature/menyu-chegirma, origin/feature/menyu-chegirma) HEAD@{1}: pull --rebase (start): checkout e5e5044145e9dc6c1126ac2e86765c9c02c2d919
506c0c4 HEAD@{2}: commit: Bosh sahifa: chegirma havolasini qo'sh
a1c2e75 HEAD@{3}: checkout: moving from main to feature/menyu-chegirma

HEAD@{2} — Sardorning commiti, 506c0c4. Uni cherry-pick bilan qaytaramiz va yuboramiz:

bash
git cherry-pick 506c0c4
git push
text
[feature/menyu-chegirma 2b60545] Bosh sahifa: chegirma havolasini qo'sh
 Date: Thu Oct 22 09:20:00 2026 +0500
 1 file changed, 1 insertion(+)
To https://github.com/login/bahor.git
   e5e5044..2b60545  feature/menyu-chegirma -> feature/menyu-chegirma

Bu safar omad kulib boqdi: Sardor o'z commitini o'z kompyuterida qutqardi. Agar commit faqat GitHub'da bo'lsa (masalan, Sardor uni boshqa kompyuterdan yuborgan va o'sha nusxa yo'q bo'lsa) — --force uni butunlay yo'qotishi mumkin edi.

8. --force-with-lease — xavfsiz majburlash

8.1 Qanday ishlaydi?

--force — "nima bo'lsa ham, ustidan yoz". --force-with-lease (ijara bilan majburlash) — "GitHub'dagi branch hali ham men oxirgi ko'rgan joyda bo'lsa — yoz; aks holda to'xta".

"Oxirgi ko'rgan joy" — sizdagi origin/feature/..., ya'ni oxirgi fetch yoki push paytidagi surat. Git hujjati buni ijaraga o'xshatadi: siz branchni "ijaraga olasiz" va kimdir o'zgartirmagan ekan, ijara amal qiladi.

flowchart TD
  A["git push --force-with-lease"] --> B{"GitHub'dagi branch<br/>= origin/... ?"}
  B -->|"ha"| C["Yozadi:<br/>forced update"]
  B -->|"yo'q"| D["To'xtaydi:<br/>stale info"]
  D --> E["git fetch, ko'rib chiqish,<br/>yangi ishni qo'shish"]
  E --> A

Nimaga qarang: stale info — xato emas, himoya. U sizni boshqa odamning ishini ko'r-ko'rona o'chirishdan to'xtatdi.

8.2 To'g'ri yo'l: feature branchni yangilash

Eng ko'p uchraydigan holat. main ga yangi commit qo'shildi (Sardor aloqa sahifasiga telefon yozdi). Aziz o'z branchini yangi main ustiga ko'chirmoqchi — kodni tekshiradigan hamkasb (reviewer) PR'dan oldin ko'pincha shuni so'raydi (Rebase darsidagi "rebase qilib yuboring").

bash
git pull
git log --oneline --graph --all -6
text
From https://github.com/login/bahor
   e5e5044..2b60545  feature/menyu-chegirma -> origin/feature/menyu-chegirma
   f42cff1..167fdc7  main                   -> origin/main
Updating e5e5044..2b60545
Fast-forward
 index.html | 1 +
 1 file changed, 1 insertion(+)
* 167fdc7 (origin/main, origin/HEAD) Aloqa: telefon raqamini qo'sh
| * 2b60545 (HEAD -> feature/menyu-chegirma, origin/feature/menyu-chegirma) Bosh sahifa: chegirma havolasini qo'sh
| * e5e5044 Menyu: dushanbalik chegirmani qo'sh
|/  
* f42cff1 (main) Bosh sahifa: "har kuni" so'zini qo'sh
* 9a65906 Bosh sahifa: ochilish vaqtini 8:00 qil
* 1ef64f4 Bosh sahifa: ish vaqtini qo'sh

Birinchi qadam — git pull: branchdagi Sardorning commitini olib keldi (va origin/main ni ham yangiladi). Endi Aziz hamma narsani ko'rgan. Rebase:

bash
git rebase origin/main
git status
text
Successfully rebased and updated refs/heads/feature/menyu-chegirma.
On branch feature/menyu-chegirma
Your branch and 'origin/feature/menyu-chegirma' have diverged,
and have 3 and 2 different commits each, respectively.
  (use "git pull" if you want to integrate the remote branch with yours)

nothing to commit, working tree clean

Ikkala commit qayta terildi — yangi SHA'lar. Ayrilish kutilgan: biz tarixni ataylab qayta yozdik. Oddiy push rad etiladi (non-fast-forward). Endi --force-with-lease:

bash
git push --force-with-lease
git log --oneline --graph -5
text
To https://github.com/login/bahor.git
 + 2b60545...48dc5ec feature/menyu-chegirma -> feature/menyu-chegirma (forced update)
* 48dc5ec (HEAD -> feature/menyu-chegirma, origin/feature/menyu-chegirma) Bosh sahifa: chegirma havolasini qo'sh
* c75c393 Menyu: dushanbalik chegirmani qo'sh
* 167fdc7 (origin/main, origin/HEAD) Aloqa: telefon raqamini qo'sh
* f42cff1 (main) Bosh sahifa: "har kuni" so'zini qo'sh
* 9a65906 Bosh sahifa: ochilish vaqtini 8:00 qil

O'tdi: GitHub'dagi branch hali 2b60545 da edi — Aziz ko'rgan joyda. Sardorning commiti ham, Azizniki ham joyida, tarix — to'g'ri chiziq.

8.3 Lease'ni nima aldaydi?

Git hujjati bitta ogohlantirish beradi. Lease sizdagi origin/... suratiga tayanadi. Agar biror dastur fonda o'zi git fetch qilib tursa (masalan, muharrirdagi avtomatik fetch yoqilgan bo'lsa), surat siz bilmasdan yangilanadi. Shunda --force-with-lease siz ko'rmagan commitni ham "ko'rgan" deb hisoblaydi.

Hujjatdagi yechim — qo'shimcha flag:

bash
git push --force-with-lease --force-if-includes

--force-if-includes yana bir tekshiruv qo'shadi: GitHub'dagi o'zgarishlar sizning lokal tarixingizga haqiqatan qo'shilganmi. Faqat fonda olib kelingan, lekin siz birlashtirmagan commit bo'lsa — push to'xtaydi.

8.4 Qoidalar

Branch Majburiy push
main va boshqa umumiy branchlar Hech qachon
O'zingizning feature branchingiz Faqat --force-with-lease
Ikki kishi ishlayotgan feature branch Avval kelishib olib, keyin --force-with-lease

main ni GitHub'da texnik jihatdan ham himoyalash mumkin — majburiy push'ni umuman taqiqlash. Buni Branch himoyasi darsida ko'rasiz. Portfolio'ni GitHub'ga ulaganda (Remote darsi) main ga --force-with-lease qildik — bu istisno: tarixni faqat bir marta, ko'rib chiqib almashtirdik va repoda boshqa hech kim ishlamaydi.

Tekshirib ko'ring: Sardor "--force-with-lease ham rad etdi, --force qilaman" dedi. Unga nima deysiz?

Javob

stale info — GitHub'da Sardor hali ko'rmagan commit bor degani. --force uni o'chiradi. To'g'ri yo'l: git fetch, git log --oneline --graph --all bilan kim nima yuborganini ko'rish, kerak bo'lsa git pull --rebase yoki git rebase bilan o'sha commitni o'z tarixiga qo'shish, keyin yana --force-with-lease.

9. Upstream'ni qo'lda sozlash: git branch -u

Ba'zan branchning upstream'i yo'qoladi yoki umuman sozlanmagan bo'ladi — masalan, branch -u siz yuborilgan bo'lsa. Ko'rsatish uchun upstream'ni ataylab olib tashlaymiz:

bash
git branch --unset-upstream
git pull
text
There is no tracking information for the current branch.
Please specify which branch you want to rebase against.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> main

"Joriy branch uchun kuzatuv ma'lumoti yo'q." git status ham ahead/behind ni ko'rsatmay qo'yadi. Tuzatish — Git aytgan buyruq yoki uning qisqa shakli -u:

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

nothing to commit, working tree clean

git push -u — yuborish bilan birga sozlaydi. git branch -u — hech narsa yubormasdan, faqat bog'lanishni yozadi.

10. Ko'p uchraydigan xatolar

10.1 Ko'r-ko'rona --force

Eng xavflisi. Internetdagi maslahat "push o'tmasa, -f qo'shing" deydi — va jamoadoshning ishi yo'qoladi. Majburiy push kerak bo'lsa — faqat --force-with-lease, faqat o'z branchingizda.

10.2 Need to specify how to reconcile divergent branches

macOS/Linux'da sozlama yo'qligi. Bir marta git config --global pull.rebase true.

10.3 Tarixda "Merge branch 'main' of ..." commitlari to'planib qoldi

Windows'dagi pull.rebase=false natijasi. Global pull.rebase true qo'ying. Eski commitlar qoladi — ular allaqachon yuborilgan, ularni qayta yozmang.

10.4 cannot pull with rebase: You have unstaged changes

Commit qiling, git stash qiling yoki --autostash.

10.5 Conflict o'rtasida qolib ketish

git status interactive rebase in progress desa — rebase tugamagan. Yo yeching va git rebase --continue, yo git rebase --abort. Yarim yo'lda yangi commit qilmang.

10.6 (forced update) ni e'tiborsiz qoldirish

Fetch yoki pull chiqishida + ... va (forced update) ko'rsangiz — kimdir tarixni qayta yozgan. O'zingizda shu branchda yuborilmagan commit bo'lsa, pull'dan oldin uning SHA'sini yozib qo'ying (yoki git branch zaxira bilan zaxira branch oching).

11. Mashqlar

1-mashq (oson): Xabarni tarjima qiling

Har bir xabar nimani bildiradi va birinchi qadam qanday?

  1. ! [rejected] main -> main (fetch first)
  2. Your branch and 'origin/main' have diverged, and have 2 and 3 different commits each
  3. ! [rejected] fix/telefon -> fix/telefon (stale info)
  4. fatal: Not possible to fast-forward, aborting.
Yechim
  1. GitHub'da sizda yo'q commit bor, Git uni hali tanimaydi. Birinchi qadam — git pull.
  2. Sizda 2 ta yuborilmagan commit, GitHub'da sizda yo'q 3 ta. git pull --rebase (yoki pull.rebase true bo'lsa — git pull).
  3. --force-with-lease to'xtadi: siz oxirgi ko'rgandan beri branch o'zgargan. git fetch va ko'rib chiqish.
  4. --ff-only (yoki pull.ff only) bilan pull qildingiz, tarix esa ayrilgan. git pull --rebase bilan birlashtiring.

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

Aziz fix/telefon branchini yuborgan, keyin uni yangi main ustiga ko'chirdi:

bash
git switch fix/telefon
git fetch
git  origin/main
git push --

Barcha repolarda git pull rebase qilishi uchun:

bash
git config --global pull. true

Ishora: «To'g'ri yo'l: feature branchni yangilash» va «Doimiy sozlama» bo'limlari.

Yechim
bash
git switch fix/telefon
git fetch
git rebase origin/main
git push --force-with-lease
git config --global pull.rebase true

Rebase SHA'larni o'zgartiradi, shuning uchun oddiy push rad etiladi. --force-with-lease — GitHub'dagi branch siz fetch'da ko'rgan joyda bo'lsagina yozadi.

3-mashq (qiyin): Kim aybdor va nima qilamiz?

Ertalab Malika feature/bron-forma branchiga ikki commit yubordi. Tushda Sardor shu branchda git commit --amend qildi, push rad etildi va u git push --force yozdi. Kechqurun Malika git pull qildi va quyidagini ko'rdi:

text
 + 7a1b2c3...9d8e7f6 feature/bron-forma -> origin/feature/bron-forma  (forced update)
  1. GitHub'da nima bo'ldi va kimning ishi xavf ostida?
  2. Sardor qaysi buyruqni ishlatishi kerak edi va u nima qilardi?
  3. Malika o'z commitlarini yo'qotmaslik uchun pull'dan oldin nima qilishi kerak edi?
  4. Commitlar baribir yo'qolgandek ko'rinsa, ularni qanday topadi?

Ishora: «--force nega xavfli», «Tuzoq ichidagi tuzoq» va Reflog darsi.

Yechim
  1. Sardor GitHub'dagi branchni o'z versiyasi bilan almashtirdi. Malikaning ertalabki ikki commiti, agar Sardorda bo'lmagan bo'lsa, GitHub'dan o'chdi. Xavf ostida — Malikaning ishi.
  2. git push --force-with-lease. Sardor Malikaning commitlarini fetch qilmagan edi — lease stale info bilan to'xtardi va Sardor avval ularni olishi kerakligini bilardi.
  3. git fetch va git status bilan holatni ko'rish. (forced update) ni ko'rib, zaxira olish: git branch bron-zaxira.
  4. git reflog — commitlarning SHA'sini topadi (ular kompyuterida edi), keyin git cherry-pick <sha> va oddiy git push. Va Sardor bilan gaplashish — keyingi safar kelishib olish uchun.

4-mashq: Portfolio qadami — GitHub'da tahrir, kompyuterda commit

Portfolio endi GitHub'da. Ba'zan faylni GitHub saytida to'g'ridan-to'g'ri tahrirlaysiz — shunda tarix ayriladi. Buni xavfsiz sharoitda sinaymiz.

  1. git config --global pull.rebase true qo'ying va git config --show-scope --get-all pull.rebase bilan tekshiring.
  2. GitHub'da login.github.io → sayt/haqimda/index.html → qalam belgisi (Edit) → bitta gap qo'shing → Commit changes. Xabar: Haqimda: yangi gap qo'sh.
  3. Kompyuterda pull qilmasdan sayt/aloqa/index.html ga o'zgarish kiriting va commit qiling: Aloqa: Telegram havolasini yangila.
  4. git push — qanday xabar chiqdi? git fetch va git status — nechta va nechta?
  5. git pull, keyin git log --oneline --graph -4 va git push.
  6. mashqlar/07/27-ajralgan-tarix/javoblar.md ga 4-qadamdagi xabarni va 5-qadamdagi grafikni yozing. Commit: 07/27: ajralgan tarix mashqlari javoblarini qo'sh, keyin git push.
Yechim
bash
git config --global pull.rebase true
git config --show-scope --get-all pull.rebase
cd ~/kurs/portfolio
code sayt/aloqa/index.html
git add sayt/aloqa/index.html
git commit -m "Aloqa: Telegram havolasini yangila"
git push
git fetch
git status
git pull
git log --oneline --graph -4
git push

4-qadamda ! [rejected] main -> main (fetch first), fetch'dan keyin have 1 and 1 different commits each. 5-qadamda Successfully rebased, grafik esa to'g'ri chiziq: sizning commitingiz GitHub'dagi tahrir ustida. Push'dan keyin Pages workflow'i ishga tushadi va sayt ikkala o'zgarish bilan yangilanadi.

Agar ikkala tahrir bitta qatorga tushsa — «pull --rebase paytida conflict» bo'limidagi kabi yechasiz. --force bu mashqda umuman kerak emas.

12. Real ishda

  • Har kunlik: pull.rebase true va git pull — eng ko'p tarqalgan sozlama. Ko'p jamoalar buni yangi xodimga birinchi kuni aytadi.
  • PR yangilash: "branch'ingizni main ustiga rebase qiling" — keyin --force-with-lease. Bu Pull Request bilan ishlashning odatiy qismi.
  • Himoya: jamoalar main ga majburiy push'ni GitHub sozlamalari bilan taqiqlaydi (Branch himoyasi). VS Code va boshqa vositalarda ham "Force Push" tugmasi odatda lease bilan ishlaydi.
  • Intervyuda: "--force va --force-with-lease farqi?", "git pull va git pull --rebase farqi?", "push rejected bo'lsa nima qilasiz?" — uchala savolga javob shu darsda.

Xulosa

  • rejected (fetch first) / (non-fast-forward) — GitHub'da sizda yo'q commit bor; avval birlashtiring.
  • have diverged, N and M — ikki tomonda ham yangi commit: merge, rebase yoki ff-only.
  • git pull --rebase yuborilmagan commitlaringizni yangi tarix ustiga teradi; pull.rebase true — doimiy.
  • Windows'da system'da pull.rebase=false bor — global sozlama uni bosib o'tadi.
  • Yuborilgan tarixni qayta yozsangiz — faqat --force-with-lease (kerak bo'lsa --force-if-includes), main da — hech qachon.
  • Upstream yo'q bo'lsa — git branch -u origin/<branch>.

Keyingi dars: GitHub asoslari: repo, README, LICENSE, sozlamalar — repongizni GitHub'da professional ko'rinishga keltiramiz: README, litsenziya, tavsif va sozlamalar.

Manbalar

  • Git hujjati: "git-push" (--force-with-lease, --force-if-includes va "Note about fast-forwards"), "git-pull", "git-config" (pull.rebase, pull.ff, rebase.autoStash) — git-scm.com/docs
  • GitHub Docs: "Dealing with non-fast-forward errors", "Pushing commits to a remote repository" — docs.github.com
  • Pro Git kitobi: "Rebasing" (The Perils of Rebasing) — git-scm.com/book
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Git push rejected: ajralgan tarix, git pull --rebase va --force-with-lease — IlmHamroh