git push — o'zgarishlarni GitHub ga yuborish, upstream sozlash

~15 daq · Git · GitHub bilan ishlash

Muammodan boshlaylik

Siz bugun 6 ta commit qildingiz. Ular faqat sizning kompyuteringizda. Hamkasblaringiz ularni ko'rmaydi, CI ularni test qilmaydi, va noutbuk bugun kechasi buzilsa — bir kunlik ish yo'qoladi.

Lokal commitlarni GitHub ga yuborish — git push.


Birinchi push — upstream sozlash

Yangi branch yaratdingiz va birinchi marta push qilmoqchisiz:

git switch -c feature/savat
# ... commitlar ...
git push
fatal: The current branch feature/savat has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/savat

Git so'rayapti: "Bu branch ni qayerga yuboray?" Birinchi marta aytish kerak:

git push -u origin feature/savat
Enumerating objects: 12, done.
...
To github.com:otabek/dokon.git
 * [new branch]      feature/savat -> feature/savat
branch 'feature/savat' set up to track 'origin/feature/savat'.
  • origin — qaysi remote ga
  • feature/savat — qaysi branch ni
  • -u (--set-upstream) — bog'lanishni eslab qolish

Endi bu branch upstream ga ega: origin/feature/savat. Keyingi safar shunchaki:

git push
git pull

Har safar -u yozmaslik

git config --global push.autoSetupRemote true

Endi yangi branch da oddiy git push avtomatik -u origin <branch> qiladi (3-dars).


Upstream ni ko'rish

git branch -vv
* feature/savat  e5f6a7b [origin/feature/savat: ahead 2] Savat: miqdor tanlash
  main           a3f9c2b [origin/main] Bloklangan foydalanuvchilar
  tajriba        9f8e7d6 Redis kesh sinovi
  • [origin/feature/savat: ahead 2] — upstream bor, 2 ta push qilinmagan commit
  • [origin/main] — sinxron
  • tajriba — upstream yo'q (faqat lokal)

git status ham ko'rsatadi:

Your branch is ahead of 'origin/feature/savat' by 2 commits.
  (use "git push" to publish your local commits)

Push rad etilganda

Eng ko'p uchraydigan holat:

git push
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:otabek/dokon.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.

Hamkasbingiz siz bilan bir vaqtda main ga push qilgan. GitHub dagi main da sizda yo'q commitlar bor:

 GitHub:   ●──●──●──X          (X — hamkasbniki)
 Siz:      ●──●──●──Y          (Y — sizniki)

Push qilsangiz — X yo'qolardi. Git buni ruxsat bermaydi. Yechim — avval ularning ishini oling:

git pull                  # X ni olib, Y bilan birlashtirish (22-dars)
git push                  # endi muvaffaqiyatli

[!WARNING] "Push rad etildi" ga javob — git pull, git push --force emas. --force GitHub dagi tarixni sizniki bilan almashtiradi va hamkasbingizning X commit ini o'chiradi. Ko'p jamoalarda main ga force push umuman taqiqlangan (branch protection, 23-dars).


Force push — qachon va qanday

Faqat bitta holat: o'z shaxsiy branch ingiz tarixini ataylab qayta yozdingiz (rebase, commit --amend — 17, 26-darslar) va push qilingan versiyani almashtirishingiz kerak.

git push --force-with-lease
--force --force-with-lease
Tekshiruv Yo'q — har qanday holatda ustidan yozadi Remote siz oxirgi ko'rgan holatdami?
Kimdir push qilgan bo'lsa Ularning ishi yo'qoladi Rad etadi

Har doim --force-with-lease. Qisqartma alias:

git config --global alias.pushf "push --force-with-lease"

Boshqa push shakllari

git push origin main                        # aniq branch ni
git push origin feature/savat:feature/cart  # boshqa nom bilan
git push origin --delete feature/savat      # remote branch ni o'chirish
git push --tags                             # barcha teglarni (36-dars)
git push origin v1.2.0                      # bitta tegni
git push --all                              # barcha lokal branch larni (kamdan-kam)
git push --dry-run                          # nima yuborilishini ko'rsatish, yubormasdan

Qachon push qilish kerak?

  • Har kun oxirida — kamida. Kompyuter buzilsa — ish yo'qolmaydi
  • PR ochishdan oldin (23-dars)
  • Feature branch ni — tez-tez, hatto ish tugamagan bo'lsa ham: zaxira va CI testlari uchun
  • main ga — to'g'ridan-to'g'ri emas; PR orqali (ko'p jamoalarda)

Push qilishdan oldin:

git log origin/main..HEAD --oneline    # nima yuborilyapti?
git status                              # commit qilinmagan narsa qolmadimi?

[!TIP] Push qilingan commitni "o'zgartirish" (amend, rebase) — boshqalarga muammo. Shuning uchun lokal tarixni push dan oldin tozalang (17-dars, rebase -i): push dan keyin tarix — "nashr qilingan".


Nima uchun shunday?

Nima uchun Git push ni rad etadi — mening commitlarimni hamkasbnikidan keyin avtomatik qo'shib qo'ya olmaydimi?

Chunki bu merge — va merge da conflict bo'lishi mumkin (16-dars). Agar server avtomatik birlashtirsa: conflict ni kim hal qiladi? Serverda muharrir yo'q, va u kodni tushunmaydi. Bundan tashqari, birlashtirilgan kod hech kim tomonidan sinab ko'rilmagan bo'lardi. Shuning uchun Git ning qoidasi: push — faqat fast-forward (sizning commitlaringiz remote ning davomi bo'lsa). Birlashtirish esa doim lokalda, siz tomonidan bajariladi — conflict larni ko'rasiz, testlarni ishga tushirasiz, keyin push qilasiz. Mas'uliyat — kodni yozgan odamda.


Xulosa

Eslab qoling:

  • git push -u origin branch — birinchi push + upstream eslab qolish
  • Keyin — shunchaki git push; push.autoSetupRemote true — -u siz
  • git branch -vv — upstream lar va ahead/behind
  • "rejected (fetch first)" → git pull, keyin git push
  • Force — faqat o'z branch ingizda, faqat --force-with-lease
  • git push origin --delete branch — remote branch ni o'chirish
  • Har kuni push — zaxira; tarixni push dan oldin tozalang

Keyingi dars

22-dars: git pull va git fetch — farqi, qachon qaysinisini ishlatish kerak