git checkout va git switch — branch lar orasida o'tish

~10 daq · Git · Branch va Merge

Muammodan boshlaylik

Internetdagi qo'llanmalarda:

git checkout feature/savat
git checkout -b feature/yangi
git checkout -- index.html
git checkout a3f9c2b

To'rt xil vazifa, bitta buyruq. Branch ga o'tish, branch yaratish, fayldagi o'zgarishlarni o'chirish, eski commit ga borish. Bitta harf xatosi — va siz branch ga o'tish o'rniga ishingizni o'chirib yuborasiz.

Shuning uchun Git 2.23 (2019) da checkout ikkiga bo'lindi: git switch — branch lar uchun, git restore — fayllar uchun.


git switch — branch ga o'tish

git switch feature/savat
Switched to branch 'feature/savat'

Nima bo'ladi:

  1. HEAD feature/savat ga o'tadi
  2. Ishchi papkadagi fayllar o'sha branch holatiga o'zgaradi

Muharrirda ochiq fayllar ham o'zgaradi — main da yo'q fayllar paydo bo'ladi, ba'zilari yo'qoladi yoki boshqacha ko'rinadi. Bu normal: siz boshqa "parallel olam" ga o'tdingiz.

Asosiy shakllar

git switch main                       # mavjud branch ga
git switch -c feature/tolov           # yangi branch yaratib, o'tish
git switch -c hotfix/narx main        # main dan yangi branch
git switch -                          # oldingi branch ga qaytish

git switch - — ikki branch orasida tez "sakrash" uchun (Linux dagi cd - kabi).

Remote branch

Hamkasbingiz GitHub ga feature/tolov ni push qildi. Siz uni olmoqchisiz:

git fetch
git switch feature/tolov
branch 'feature/tolov' set up to track 'origin/feature/tolov'.
Switched to a new branch 'feature/tolov'

Lokal branch yo'q, lekin shu nomdagi remote branch bor — Git avtomatik lokal nusxa yaratadi va uni bog'laydi (22-dars).


Saqlanmagan o'zgarishlar bilan o'tish

Siz main da ba'zi fayllarni o'zgartirdingiz (commit qilmadingiz) va branch almashtirmoqchisiz. Ikki holat:

1. O'zgarishlar ziddiyatga kirmaydi — Git ularni o'zingiz bilan olib o'tadi:

Switched to branch 'feature/savat'
M       README.md

O'zgarishlar — ishchi papkada, ular hech qaysi branch ga "tegishli" emas, toki commit qilinmaguncha.

2. Ziddiyat bor — o'zgartirgan faylingiz boshqa branch da ham boshqacha:

error: Your local changes to the following files would be overwritten by checkout:
        src/narx.js
Please commit your changes or stash them before you switch branches.
Aborting

Git ishingizni himoya qiladi va o'tishni rad etadi. Variantlar:

# A) Commit qilish
git add . && git commit -m "Narx formati: yarim tayyor"

# B) Vaqtincha yashirish (18-dars)
git stash
git switch feature/savat
# ... keyin qaytib:
git switch main
git stash pop

[!TIP] Eng xotirjam odat: branch almashtirishdan oldin toza holat — git status "nothing to commit". Ish yarim bo'lsa — "WIP" commit yoki stash.


git restore — fayllar uchun

checkout ning ikkinchi yarmi:

git restore index.html                # working dagi o'zgarishlarni bekor qilish ⚠️
git restore .                         # hamma fayllarda ⚠️
git restore --staged index.html       # staging dan olish (fayl o'zgarmaydi)
git restore --source=HEAD~2 app.js    # faylni 2 commit oldingi holatga qaytarish
git restore --source=main config.js   # faylni main dagi versiya bilan almashtirish

[!WARNING] git restore fayl (va eski git checkout -- fayl) — commit qilinmagan o'zgarishlarni qaytarib bo'lmas darajada o'chiradi. Git ularni hech qayerda saqlamagan. Ishlatishdan oldin git diff fayl bilan nima yo'qolishini ko'ring.


checkout — eski, lekin hali hamma joyda

git checkout ishlashda davom etadi va ko'p qo'llanmalarda, skriptlarda va hamkasblar nutqida uchraydi. Moslik jadvali:

Eski (checkout) Yangi
git checkout main git switch main
git checkout -b yangi git switch -c yangi
git checkout -- fayl git restore fayl
git checkout HEAD~2 -- fayl git restore --source=HEAD~2 fayl
git checkout a3f9c2b git switch --detach a3f9c2b

Yangi kodda switch va restore ni ishlating — ular aniqroq va xatoga kamroq moyil. Lekin checkout ni o'qiy olishingiz kerak.


Detached HEAD — "uzilgan" holat

Eski commit ni ko'rish uchun:

git switch --detach a3f9c2b           # yoki: git checkout a3f9c2b
HEAD is now at a3f9c2b Bloklangan foydalanuvchilar tizimga kira olmasin

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches...

Odatda HEAD branch ga ishora qiladi, branch esa commit ga. "Detached" holatda HEAD to'g'ridan-to'g'ri commit ga ishora qiladi:

 Normal:                     Detached:
   HEAD → main → ●              HEAD → ●  (hech qaysi branch emas)

Bu eski versiyani ko'rish, sinash, xatoni qidirish uchun yaxshi. Lekin bu holatda commit qilsangiz — ular hech qaysi branch ga tegishli emas va boshqa branch ga o'tganingizda "yo'qoladi".

Chiqish:

git switch main                       # shunchaki branch ga qaytish
git switch -c tajriba                 # yoki — qilgan ishingizni yangi branch da saqlash

[!INFO] detached HEAD — xato emas, qo'rqinchli ham emas. Shunchaki "siz hech qaysi branch da emassiz" degani. Qilgan commitlaringiz yo'qolgan bo'lsa ham — git reflog (31-dars) ularni topadi.


Nima uchun shunday?

Nima uchun Git ishchi papkadagi fayllarni branch almashtirganda to'liq almashtiradi — har bir branch uchun alohida papka qulayroq emasmi?

Bitta papka — bir nechta afzallik: muharrir, terminal, node_modules, ishlayotgan dev server — hammasi joyida qoladi; branch almashtirish — bir soniya, nusxa olish emas. Git faqat farq qiluvchi fayllarni o'zgartiradi, shuning uchun bu juda tez. Lekin ba'zan haqiqatan ikki branch bir vaqtda kerak bo'ladi (masalan, uzoq test ishlayotganda boshqa branch da tuzatish) — buning uchun Git da git worktree bor: bitta repozitoriy, bir nechta ishchi papka (46-dars).


Xulosa

Eslab qoling:

  • git switch nom — branch ga o'tish; fayllar o'sha branch holatiga o'zgaradi
  • git switch -c nom — yaratish + o'tish; git switch - — oldingisiga
  • Remote branch: git fetch → git switch nom — avtomatik bog'lanadi
  • Ziddiyatli saqlanmagan o'zgarishlar — avval commit yoki stash
  • git restore fayl — o'zgarishlarni bekor qilish (qaytarib bo'lmaydi!); --staged — staging dan
  • checkout — eski universal buyruq; yangi kodda switch + restore
  • Detached HEAD — commit ga to'g'ridan-to'g'ri; chiqish — git switch main yoki switch -c

Keyingi dars

15-dars: git merge — Fast-forward va 3-way merge, farqlari