git reset — soft, mixed, hard — farqlari va qachon ishlatiladi

~20 daq · Git · Git Tarixini Boshqarish

Muammodan boshlaylik

Uch xil vaziyat:

  1. Oxirgi 3 ta commit ni bittaga birlashtirib, qayta commit qilmoqchisiz
  2. git add . qildingiz va staging ga keraksiz fayllar tushdi
  3. Oxirgi 2 soatdagi tajriba to'liq muvaffaqiyatsiz — hammasini o'chirib, oxirgi commit ga qaytmoqchisiz

Uchala holatga ham javob — git reset, faqat turli rejimlarda. Bu Git dagi eng kuchli va eng xavfli buyruqlardan biri, shuning uchun uni yaxshilab tushunish kerak.


Reset nima qiladi

git reset <commit> — joriy branch ko'rsatkichini boshqa commit ga suradi. Rejimga qarab — staging va ishchi papkani ham o'zgartiradi.

 Oldin:                          git reset HEAD~2 dan keyin:
  ●────●────A────B────C   main     ●────●────A    main
                      ↑                      ↑
                     HEAD                   HEAD
                                    (B va C — branch dan "chiqarildi")

B va C commitlari darhol yo'qolmaydi — reflog ularni eslaydi (31-dars). Lekin main endi ularga ishora qilmaydi.


Uch rejim

6-darsdagi uch zona — reset rejimlarini tushunish kaliti:

Rejim Branch ko'rsatkichi Staging Ishchi papka
--soft ✅ Suriladi Tegilmaydi Tegilmaydi
--mixed (standart) ✅ Suriladi ✅ Tozalanadi Tegilmaydi
--hard ✅ Suriladi ✅ Tozalanadi ⚠️ O'chiriladi

--soft — commitlarni bekor qilish, o'zgarishlar staged

git reset --soft HEAD~3
git status
Changes to be committed:
        modified:   src/savat.js
        modified:   src/savat.css
        new file:   src/miqdor.js

Oxirgi 3 commit dagi barcha o'zgarishlar — staging da, commit ga tayyor. Endi bitta toza commit:

git commit -m "Savat: miqdor tanlash funksiyasi"

Qachon: bir nechta commitni bittaga birlashtirish (squash) — rebase -i ga oddiy muqobil.

--mixed — commitlar va staging bekor, fayllar joyida

git reset HEAD~1            # --mixed — standart, yozish shart emas

O'zgarishlar ishchi papkada qoladi, lekin staging dan chiqariladi. Ularni qaytadan, boshqacha guruhlab add qilish mumkin.

Qachon: oxirgi commit ni "ochib", uni bir nechta mantiqiy commit ga bo'lish (git add -p bilan, 7-dars).

--hard — hammasini o'chirish

git reset --hard HEAD

Ishchi papka va staging — oxirgi commit holatiga. Barcha commit qilinmagan o'zgarishlar yo'qoladi.

git reset --hard HEAD~2     # oxirgi 2 commit va barcha o'zgarishlar — yo'q
git reset --hard origin/main   # lokal main ni GitHub dagi holatga to'liq moslashtirish

[!WARNING] git reset --hard — Git dagi eng xavfli kundalik buyruq. Commit qilinmagan o'zgarishlar (ishchi papka va staging) qaytarib bo'lmas darajada o'chadi — Git ularni hech qachon saqlamagan. Commitlar esa reflog orqali tiklanadi. Ishlatishdan oldin: git status va git stash — xavfsizlik uchun.


Fayllar uchun reset

Commit ko'rsatmasdan, fayl nomi bilan — faqat staging ga ta'sir qiladi:

git reset src/config.js       # = git restore --staged src/config.js

Zamonaviy Git da buning uchun git restore --staged (7, 14-darslar) aniqroq. reset ni eski qo'llanmalarda ko'rasiz.


Push qilingan commitlar

 GitHub:  ●──●──A──B──C
 Siz:     ●──●──A          (reset HEAD~2 dan keyin)

git push rad etiladi. --force bilan push qilsangiz — B va C GitHub dan yo'qoladi, hamkasblaringizda esa ular qoladi. Tarixlar ajraladi.

[!WARNING] Push qilingan va boshqalar ishlatayotgan commitlarni reset qilmang. Ularni bekor qilish uchun — git revert (keyingi dars): u tarixni o'chirmaydi, yangi "bekor qiluvchi" commit qo'shadi.

Faqat lokal, hali push qilinmagan commitlar — reset uchun xavfsiz hudud.


Tipik holatlar — tezkor jadval

Vaziyat Buyruq
Oxirgi commit ni bekor qilish, o'zgarishlar staged qolsin git reset --soft HEAD~1
Oxirgi commit ni bekor qilish, o'zgarishlarni qayta ko'rib chiqish git reset HEAD~1
Oxirgi 3 commit ni bittaga git reset --soft HEAD~3 && git commit
Staging dan barcha fayllarni olish git reset (yoki git restore --staged .)
Barcha lokal o'zgarishlarni o'chirish git reset --hard ⚠️
Lokal branch ni GitHub dagiga to'liq moslashtirish git fetch && git reset --hard origin/main ⚠️
Noto'g'ri branch ga commit qildim (main ga, feature o'rniga) Pastga qarang

Noto'g'ri branch ga commit qildim

main da 2 ta commit qildingiz, lekin ular feature/savat da bo'lishi kerak edi (hali push qilinmagan):

git branch feature/savat           # 1. Joriy holatda yangi branch (commitlar unda saqlanadi)
git reset --hard HEAD~2            # 2. main ni 2 qadam orqaga
git switch feature/savat           # 3. Commitlar shu yerda

Reset dan qo'rqmaslik — reflog

Xato reset qildingizmi? Commitlar yo'qolmagan:

git reflog
a3f9c2b HEAD@{0}: reset: moving to HEAD~2
e5f6a7b HEAD@{1}: commit: Savat: miqdor tanlash
...
git reset --hard e5f6a7b           # reset dan oldingi holatga qaytish

Batafsil — 31-dars. Yodda tuting: reflog commitlarni qutqaradi; commit qilinmagan o'zgarishlarni — yo'q.


Nima uchun shunday?

Nima uchun reset ning uchta rejimi bor — bittasi yetmaydimi?

Chunki "orqaga qaytish" ning uch xil ma'nosi bor, va ular uchta zonaga mos keladi (6-dars). Ba'zan siz faqat tarixni qayta yozmoqchisiz, lekin ishni saqlab (--soft); ba'zan tarixni va tanlovni (staging) bekor qilib, fayllarni qoldirmoqchisiz (--mixed); va ba'zan haqiqatan hammasini tashlab yubormoqchisiz (--hard). Bitta "bekor qil" tugmasi sizni har safar yo kam, yo ortiqcha qilishga majbur qilardi. Uchta rejim — aniqlik: siz aynan nimani yo'qotishga tayyor ekaningizni aytasiz.


Xulosa

Eslab qoling:

  • git reset <commit> — branch ko'rsatkichini surish
  • --soft — faqat commitlar bekor, o'zgarishlar staged
  • --mixed (standart) — commitlar va staging bekor, fayllar joyida
  • --hard — hammasi o'chadi, commit qilinmaganlar qaytmaydi ⚠️
  • Commitlarni birlashtirish: reset --soft HEAD~N + commit
  • Faqat lokal commitlar uchun; push qilinganlar — revert
  • Noto'g'ri branch: git branch yangi → reset --hard HEAD~N → switch yangi
  • Xato reset — git reflog qutqaradi

Keyingi dars

28-dars: git revert — commitni bekor qilish, reset dan farqi