Mundarija (37)
- Bu darsda
- 1. Nega bu kerak?
- 2. Reflog — HEAD kundaligi
- 2.1 git reflog ni o'qish
- 2.2 Vaqt bilan
- 2.3 Har branchning o'z reflogi
- 3. Retsept 1: reset --hard dan qaytish
- 3.1 Baxtsiz hodisa
- 3.2 Qaytarish
- 3.3 Qisqa yo'l: ORIG_HEAD
- 4. Retsept 2: o'chirilgan branchni tiklash
- 5. Retsept 3: noto'g'ri branchga commit
- 5.1 Yangi branch kerak edi
- 5.2 Mavjud boshqa branch kerak edi
- 6. Retsept 4: amend ni bekor qilish
- 7. Retsept 5: merge'ni bekor qilish
- 8. Retsept 6: push qilingan xato — revert
- 9. Retsept 7: drop qilingan stash
- 10. Retsept 8: add qilingan, lekin commit qilinmagan fayl
- 11. Retsept 9: qaytarib bo'lmaydigan holat
- 12. Qancha vaqt saqlanadi? gc muddatlari
- 12.1 Uchta muddat
- 12.2 Majburiy tozalash — xavfli
- 12.3 Reflog — faqat sizniki
- 13. Qaysi retsept? Xarita
- 14. Ko'p uchraydigan xatolar
- 14.1 PowerShell'da HEAD@{1}
- 14.2 Raqam surilib ketdi
- 14.3 Qutqarayotib yangi ishni yo'qotish
- 15. Mashqlar
- 1-mashq (oson): Reflogni o'qing
- 2-mashq (o'rta): Bo'sh joylarni to'ldiring
- 3-mashq (qiyin): Uch baxtsiz hodisa
- 4-mashq: Portfolio qadami — xavfsiz mashq
- 16. Real ishda
- Xulosa
- Manbalar
Git reflog: yo'qolgan commitni qaytarish va "favqulodda yordam" retseptlari
Qisqacha: Git'da commit qilingan narsa deyarli hech qachon darhol yo'qolmaydi.
git reflog— HEAD qayerlarda bo'lganining kundaligi:reset --hard, o'chirilgan branch yokiamenddan oldingi commitning SHA'si shu yerda turadi. SHA'ni topib,git reset --hard HEAD@{1}yokigit branch <nom> <sha>bilan qaytarasiz. Yozuvlar sukut bo'yicha 90 kun (yetib bo'lmaydiganlari 30 kun) saqlanadi; hech qachonaddqilinmagan o'zgarish esa haqiqatan yo'qoladi.
Bu darsda
git reflogchiqishini o'qiysiz vaHEAD@{n}nimani bildirishini tushuntira olasiz.reset --hard, o'chirilgan branch,amendva merge'dan keyin avvalgi holatni qaytarasiz.- Noto'g'ri branchga tushgan commitni kerakli branchga ko'chirasiz.
- Push qilingan xatoni
revertbilan, yo'qolgan stash va faylnigit fsckbilan qutqarasiz. - Nima qancha vaqt saqlanishini (
gcmuddatlari) va nima umuman qaytmasligini bilasiz.
Oldin bilishingiz kerak: Xatoni tuzatish 2: reset va revert, HEAD, refs va detached HEAD, Stash: yarim ishni vaqtincha chetga olish.
1. Nega bu kerak?
Kechqurun soat o'n bir. Aziz «Bahor» menyusida ishlayapti. Reset va revert darsidagi buyruqni eslab, oxirgi commitni bekor qilmoqchi bo'ldi. Lekin HEAD~1 o'rniga HEAD~2 yozib yubordi. Ikki commit — manti va chuchvara narxlari — git log dan g'oyib bo'ldi. --hard bo'lgani uchun fayllardan ham.
Birinchi o'y: "Hammasi yo'qoldi. Qaytadan yozaman."
Shoshmang. Git'ning ichida uchoqlardagi "qora quti" kabi yozuvchi qurilma bor. Samolyotda nima bo'lsa ham, qora quti har bir harakatni yozib boradi. Git'da ham HEAD har safar bir joydan boshqa joyga o'tganda — commit, reset, branch almashtirish, merge — bu yozib qo'yiladi. Commit git log dan yo'qolgan bo'lishi mumkin, lekin qora qutidan emas.
Bu dars — dori qutisi. Avval qora qutini o'qishni o'rganamiz, keyin eng ko'p uchraydigan to'qqizta "baxtsiz hodisa" uchun tayyor retsept. Har retseptni biz sinov repoda haqiqatan bajardik — natijalar haqiqiy.
2. Reflog — HEAD kundaligi
2.1 git reflog ni o'qish
«Bahor» reposida oddiy tarixga qaraymiz:
git log --onelined0dd8bb (HEAD -> main) Menyu: chuchvara narxini qo'sh
5a2cf1f Menyu: manti narxini qo'sh
07b061d Menyu: lag'mon narxini qo'sh
bd98d1b Bron: rahmat sahifasini qo'sh
b09fa2a Aloqa: sahifa yarat
9084599 Bosh sahifa: aloqa havolasini qo'sh
f4238e7 Menyu: osh narxini qo'sh
dab5bff Bahor: sayt tuzilmasini yaratEndi reflog'ga:
git reflogd0dd8bb (HEAD -> main) HEAD@{0}: commit: Menyu: chuchvara narxini qo'sh
5a2cf1f HEAD@{1}: commit: Menyu: manti narxini qo'sh
07b061d HEAD@{2}: commit: Menyu: lag'mon narxini qo'sh
bd98d1b HEAD@{3}: commit: Bron: rahmat sahifasini qo'sh
b09fa2a HEAD@{4}: commit: Aloqa: sahifa yarat
9084599 HEAD@{5}: commit: Bosh sahifa: aloqa havolasini qo'sh
f4238e7 HEAD@{6}: commit: Menyu: osh narxini qo'sh
dab5bff HEAD@{7}: commit (initial): Bahor: sayt tuzilmasini yaratHozircha ikkalasi o'xshash, chunki biz faqat commit qildik. Har qator — HEAD'ning bitta harakati:
d0dd8bb— harakatdan keyin HEAD qaysi commitda turgani.HEAD@{0}— "HEAD hozir",HEAD@{1}— "bitta harakat oldin",HEAD@{2}— "ikkita harakat oldin".commit:— harakat turi. Keyinreset:,checkout:,mergekabilarni ham ko'rasiz.- Oxiri — izoh (commit xabari yoki qayerdan qayerga o'tilgani).
Reflog (reference log) — "havolalar jurnali": HEAD va har bir branch uchi qayerlarda bo'lganining ro'yxati. Farqni aniq tushunib oling: git log tarixning hozirgi shaklini ko'rsatadi — commitlar zanjirini. git reflog esa sizning harakatlaringizni — nima qilganingiz tarixini.
2.2 Vaqt bilan
Qachon bo'lganini ham ko'rish mumkin:
git reflog -3 --date=isod0dd8bb (HEAD -> main) HEAD@{2026-10-10 09:10:00 +0500}: commit: Menyu: chuchvara narxini qo'sh
5a2cf1f HEAD@{2026-10-10 09:00:00 +0500}: commit: Menyu: manti narxini qo'sh
07b061d HEAD@{2026-10-02 10:12:00 +0500}: commit: Menyu: lag'mon narxini qo'sh-3 — oxirgi uchta yozuv. Git vaqt bilan murojaat qilishni ham tushunadi: HEAD@{1.hour.ago} — "bir soat oldin HEAD qayerda edi", main@{yesterday} — "kecha main qayerda edi". "Ertalab ishlayotgan edi, keyin nimadir buzildi" degan holatda juda qulay.
2.3 Har branchning o'z reflogi
git reflog HEAD'nikini ko'rsatadi. Har branch uchun alohida jurnal ham bor: git reflog show main. Bu dars davomida uni o'chirilgan branch retseptida ko'rasiz.
Tekshirib ko'ring:
git logda 6 ta commit,git reflogda esa 20 ta yozuv. Bu qanday bo'lishi mumkin?
Javob
Reflog commitlarni emas, HEAD harakatlarini yozadi. Branch almashtirish (checkout:), reset, merge — har biri alohida yozuv, garchi yangi commit yaratmasa ham. Bitta commitga ko'p marta qaytib kelish mumkin — u reflogda bir necha marta ko'rinadi.
3. Retsept 1: reset --hard dan qaytish
3.1 Baxtsiz hodisa
git reset --hard HEAD~2
git log --oneline -2HEAD is now at 07b061d Menyu: lag'mon narxini qo'sh
07b061d (HEAD -> main) Menyu: lag'mon narxini qo'sh
bd98d1b Bron: rahmat sahifasini qo'shManti va chuchvara log dan yo'qoldi. Qora qutini ochamiz:
git reflog -307b061d (HEAD -> main) HEAD@{0}: reset: moving to HEAD~2
d0dd8bb HEAD@{1}: commit: Menyu: chuchvara narxini qo'sh
5a2cf1f HEAD@{2}: commit: Menyu: manti narxini qo'shMana ular! Eng yangi yozuv — bizning xato reset: "HEAD~2 ga ko'childi". Undan oldingi HEAD@{1} — reset'dan oldingi holat, chuchvara commiti.
3.2 Qaytarish
Avval tekshiramiz — aynan shu commit kerakmi:
git show --oneline --stat HEAD@{1}d0dd8bb Menyu: chuchvara narxini qo'sh
menyu/index.html | 1 +
1 file changed, 1 insertion(+)Ha. Endi reset'ning o'zi bilan orqaga qaytamiz:
git reset --hard HEAD@{1}
git log --oneline -3HEAD is now at d0dd8bb Menyu: chuchvara narxini qo'sh
d0dd8bb (HEAD -> main) Menyu: chuchvara narxini qo'sh
5a2cf1f Menyu: manti narxini qo'sh
07b061d Menyu: lag'mon narxini qo'shHammasi joyida. HEAD@{1} o'rniga SHA'ni ham yozish mumkin: git reset --hard d0dd8bb. SHA — ishonchliroq: har yangi harakat bilan {1} raqami suriladi, SHA esa o'zgarmaydi.
3.3 Qisqa yo'l: ORIG_HEAD
HEAD va refs darsida ORIG_HEAD ni ko'rgan edik. Git uni "xavfli" buyruqlardan (reset, merge, rebase) oldin yozib qo'yadi. Xuddi shu xatoni takrorlab, faylga qaraymiz:
git reset --hard HEAD~2
cat .git/ORIG_HEAD
git reset --hard ORIG_HEADHEAD is now at 07b061d Menyu: lag'mon narxini qo'sh
d0dd8bb32588d674bbfefd88b65062f6e94010ee
HEAD is now at d0dd8bb Menyu: chuchvara narxini qo'shORIG_HEAD — reset'dan oldingi SHA. Lekin u faqat oxirgi xavfli buyruqni eslaydi: keyingisi uni ustidan yozadi. Xato darhol sezilsa — ORIG_HEAD; kechroq bo'lsa — reflog.
4. Retsept 2: o'chirilgan branchni tiklash
Aziz feature/bron-forma branchida ikki commit qildi va main ga qaytdi. Keyin "keraksiz" deb o'chirmoqchi bo'ldi:
git branch -d feature/bron-formaerror: the branch 'feature/bron-forma' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature/bron-forma'
hint: Disable this message with "git config set advice.forceDeleteBranch false"Git ogohlantirdi: "branch to'liq birlashtirilmagan" — unda boshqa joyda yo'q commitlar bor (Branch nima). Aziz o'qimasdan katta -D bilan o'chirdi:
git branch -D feature/bron-formaDeleted branch feature/bron-forma (was bf0c0cf).Birinchi qutqaruvchi — shu xabarning o'zi: was bf0c0cf. Terminal hali ochiq bo'lsa, shu SHA yetarli. Yopilgan bo'lsa — reflog:
git reflog -4d0dd8bb (HEAD -> main) HEAD@{0}: checkout: moving from feature/bron-forma to main
bf0c0cf HEAD@{1}: commit: Bron: ism maydonini qo'sh
638ddc8 HEAD@{2}: commit: Bron: forma skeletini qo'sh
d0dd8bb (HEAD -> main) HEAD@{3}: checkout: moving from main to feature/bron-formaPastdan tepaga o'qiymiz: main dan feature/bron-forma ga o'tildi, ikki commit qilindi, main ga qaytildi. Branchning oxirgi commiti — main ga qaytishdan oldingi yozuv, bf0c0cf. Branchni o'sha commitda qayta yaratamiz:
git branch feature/bron-forma HEAD@{1}
git log --oneline -3 feature/bron-formabf0c0cf (feature/bron-forma) Bron: ism maydonini qo'sh
638ddc8 Bron: forma skeletini qo'sh
d0dd8bb (HEAD -> main) Menyu: chuchvara narxini qo'shBranch qaytdi — ikkala commiti bilan. Nega bu ishladi? Branch nima darsini eslang: branch — shunchaki commitga yopishtirilgan yorliq. O'chirish faqat yorliqni oladi. Commitlar .git/objects da qoladi, biz esa yorliqni qayta yopishtirdik.
Bir nozik nuqta. Branch o'chirilganda uning o'z reflogi ham o'chadi:
git reflog show feature/bron-formabf0c0cf (feature/bron-forma) feature/bron-forma@{0}: branch: Created from HEAD@{1}Yangi branch jurnali bitta yozuvdan boshlandi — eski tarixi yo'q. Shuning uchun o'chirilgan branchni doim HEAD reflogidan qidirasiz.
5. Retsept 3: noto'g'ri branchga commit
5.1 Yangi branch kerak edi
Aziz aloqa sahifasiga manzil qo'shib, commit qildi. Keyin sezdi: bu yangi vazifa edi, alohida branchda bo'lishi kerak edi, u esa main da turibdi.
git log --oneline -2f111dd8 (HEAD -> main) Aloqa: manzilni qo'sh
d0dd8bb Menyu: chuchvara narxini qo'shIkki qadam: avval joriy joyda yangi branch yorlig'ini qo'yamiz, keyin main ni bir commit orqaga suramiz:
git branch fix/aloqa-manzil
git reset --hard HEAD~1
git log --oneline -1
git log --oneline -2 fix/aloqa-manzilHEAD is now at d0dd8bb Menyu: chuchvara narxini qo'sh
d0dd8bb (HEAD -> main) Menyu: chuchvara narxini qo'sh
f111dd8 (fix/aloqa-manzil) Aloqa: manzilni qo'sh
d0dd8bb (HEAD -> main) Menyu: chuchvara narxini qo'shgit branch (switch -c emas!) yorliqni qo'yadi, lekin bizni main da qoldiradi. Commit endi fix/aloqa-manzil da, main esa tozalandi.
flowchart LR
A["main: ...d0dd8bb<br/>f111dd8 (xato)"] --> B["git branch<br/>fix/aloqa-manzil"]
B --> C["git reset --hard<br/>HEAD~1"]
C --> D["main: d0dd8bb<br/>fix/aloqa-manzil: f111dd8"]Nimaga qarang: tartib muhim. Avval reset qilsangiz, commitga yorliq qolmaydi — keyin uni reflogdan qidirishga to'g'ri keladi.
5.2 Mavjud boshqa branch kerak edi
Yana bir holat: Aziz bron shartlari sahifasini main ga commit qildi, aslida u allaqachon bor feature/bron-forma branchiga tegishli edi. Bu safar cherry-pick bilan ko'chiramiz, keyin main ni tozalaymiz:
git switch feature/bron-forma
git cherry-pick main
git switch main
git reset --hard HEAD~1Switched to branch 'feature/bron-forma'
[feature/bron-forma 5f7cc94] Bron: shartlar sahifasini qo'sh
Date: Sat Oct 10 11:10:00 2026 +0500
1 file changed, 1 insertion(+)
create mode 100644 bron/shartlar.html
Switched to branch 'main'
HEAD is now at d0dd8bb Menyu: chuchvara narxini qo'shgit cherry-pick main — "main ning oxirgi commitini ol". Cherry-pick darsida aytganimizdek, branch nomi yozilsa, uning faqat uchidagi commit olinadi — aynan bizga kerak bo'lgani.
Diqqat: 3-retseptning ikkala varianti ham
maintarixini qayta yozadi. Bu faqat xato commit hali hech kimga yuborilmagan bo'lsa mumkin. Yuborilgan bo'lsa — 6-retsept.
6. Retsept 4: amend ni bekor qilish
Xatoni tuzatish 1 darsida commit --amend oxirgi commitni "tuzatishini" ko'rgan edik. Aslida u eski commitni o'zgartirmaydi — yangisini yaratadi. Aziz "Menyu: ko'k choy narxini qo'sh" commitiga adashib somsa narxini ham qo'shib yubordi:
git add menyu/index.html
git commit --amend --no-edit
git reflog -2[main 480e448] Menyu: ko'k choy narxini qo'sh
Date: Sat Oct 10 12:00:00 2026 +0500
1 file changed, 2 insertions(+)
480e448 (HEAD -> main) HEAD@{0}: commit (amend): Menyu: ko'k choy narxini qo'sh
7dfc18c HEAD@{1}: commit: Menyu: ko'k choy narxini qo'shReflog ikkala versiyani ko'rsatyapti: 7dfc18c — asl, 480e448 — amend'dan keyingisi. Asl commitga qaytamiz, lekin o'zgarishlarni yo'qotmaymiz — reset darsidagi --soft:
git reset --soft HEAD@{1}
git status -s
git log --oneline -1M menyu/index.html
7dfc18c (HEAD -> main) Menyu: ko'k choy narxini qo'shCommit asl holatiga qaytdi. Somsa qatori esa qutida turibdi — uni alohida commit qilish yoki olib tashlash mumkin.
7. Retsept 5: merge'ni bekor qilish
Aziz feature/bron-forma ni main ga birlashtirdi, keyin Jasur aka "bron hali tayyor emas" dedi. Merge hali yuborilmagan:
git merge --no-ff --no-edit feature/bron-forma
git reset --hard ORIG_HEAD
git log --oneline -1Merge made by the 'ort' strategy.
bron/index.html | 2 ++
bron/shartlar.html | 1 +
2 files changed, 3 insertions(+)
create mode 100644 bron/shartlar.html
HEAD is now at 7dfc18c Menyu: ko'k choy narxini qo'sh
7dfc18c (HEAD -> main) Menyu: ko'k choy narxini qo'shmerge ham ORIG_HEAD ni yozadi — merge'dan oldingi holat. reset --hard ORIG_HEAD hammasini ortga qaytaradi. rebase dan keyin ham xuddi shunday ishlaydi (Rebase).
8. Retsept 6: push qilingan xato — revert
Aziz osh narxini 3 500 deb yozdi (bitta nol tushib qoldi) va commitni GitHub'ga yuborib ulgurdi. Endi reset bilan tarixni qayta yozish mumkin emas — boshqalar bu commitni allaqachon olgan bo'lishi mumkin (rebase oltin qoidasi aynan shu haqda).
Xavfsiz yo'l — Reset va revert darsidagi revert: teskari o'zgarishli yangi commit.
git revert --no-edit HEAD
git log --oneline -3[main 330abfe] Revert "Menyu: osh narxini yangila"
Date: Sat Oct 10 13:05:00 2026 +0500
1 file changed, 1 deletion(-)
330abfe (HEAD -> main) Revert "Menyu: osh narxini yangila"
0b1109d Menyu: osh narxini yangila
7dfc18c Menyu: ko'k choy narxini qo'sh--no-edit — muharrirni ochmasdan, Git taklif qilgan xabarni qabul qil. Xato commit tarixda qoldi, lekin uning ta'siri bekor qilindi. Keyin to'g'ri narxni yangi commit bilan yozasiz va ikkalasini yuborasiz.
9. Retsept 7: drop qilingan stash
Stash darsida drop stash SHA'sini chiqarishini ko'rgan edik. Aziz chegirma g'oyasini stash qildi va adashib o'chirdi:
git stash push -m "chegirma g'oyasi"
git stash dropSaved working directory and index state On main: chegirma g'oyasi
Dropped refs/stash@{0} (91e0302aa12706a8ea2843a2296fd09b467c798f)Terminal ochiq bo'lsa — qavs ichidagi SHA bilan darhol: git stash apply 91e0302.... Yopilgan bo'lsa-chi? Stash reflogda yo'q — u o'chirilgan. Bu yerda boshqa asbob kerak: git fsck.
git fsck (file system check) — Git bazasining "tibbiy ko'rigi". U .git/objects dagi barcha obyektlarni tekshiradi. --lost-found bilan esa hech narsa ko'rsatmayotgan, "yetim" obyektlarni topadi:
git fsck --lost-founddangling commit 02a2b04872e51f0e242a5d80d9dfb9ad969bef07
dangling commit 3909f7935953a543a74ce7056b85d1a5ab59cb6a
dangling commit 480e4480558c84c4cd74d357a7e78528560fa7a4
dangling commit 91e0302aa12706a8ea2843a2296fd09b467c798fDangling — "osilib qolgan": hech bir branch, tag yoki boshqa obyekt ko'rsatmaydigan commit. To'rttasi bor. Qaysi biri stash? Xabarlarini ko'ramiz — --no-walk "faqat shu commitlarning o'zini ko'rsat, otalariga o'tma" degani:
git log --oneline --no-walk 02a2b04 3909f79 480e448 91e030291e0302 On main: chegirma g'oyasi
02a2b04 Merge branch 'feature/bron-forma'
480e448 Menyu: ko'k choy narxini qo'sh
3909f79 Bron: shartlar sahifasini qo'shRo'yxatda darsdagi boshqa "baxtsiz hodisalar" ham bor: bekor qilingan merge, amend qilingan commit, main dan olib tashlangan shartlar commiti. Stash — On main: chegirma g'oyasi. Uni qaytaramiz:
git stash apply 91e0302
git status -s M index.html(apply ning to'liq git status chiqishini qisqartirdik.) Chegirma qatori papkaga qaytdi.
10. Retsept 8: add qilingan, lekin commit qilinmagan fayl
Aziz yangi tadbirlar.html sahifasini yaratdi va git add qildi. Commit qilmasdan, boshqa ishni tozalash uchun git reset --hard yozdi:
git reset --hard
ls tadbirlar.htmlHEAD is now at 330abfe Revert "Menyu: osh narxini yangila"
ls: cannot access 'tadbirlar.html': No such file or directoryFayl yo'q. Commit ham yo'q — reflog yordam bermaydi. Lekin bitta umid bor. Git ichkaridan darsida ko'rgansiz: git add fayl mazmunini darhol .git/objects ga blob qilib yozadi. Blob hali o'sha yerda:
git fsck --lost-founddangling commit 02a2b04872e51f0e242a5d80d9dfb9ad969bef07
dangling blob 1770056af463d7af599325e42ea7a13eeb3efe9a
dangling commit 3909f7935953a543a74ce7056b85d1a5ab59cb6a
...Yangi qator — dangling blob. --lost-found ularni .git/lost-found/other/ papkasiga ham yozib qo'yadi. Mazmuniga qaraymiz:
git show 1770056<h1>Yangi sahifa: tadbirlar</h1>Aynan o'sha. Faylni qayta yozamiz — > bilan (Oqimlar va yo'naltirish):
git show 1770056 > tadbirlar.html
git status -s?? tadbirlar.htmlBlob faqat mazmunni saqlaydi, fayl nomini emas. Shuning uchun ko'p blob bo'lsa, har birini ochib, qaysi fayl ekanini mazmunidan taniysiz.
11. Retsept 9: qaytarib bo'lmaydigan holat
Endi halol gap. Aziz aloqa sahifasiga bir qator yozdi, add ham, commit ham qilmadi va git reset --hard yozdi. git fsck --lost-found ni tekshirdik — ro'yxat oldingisi bilan bir xil, yangi blob yo'q.
Git hech qachon ko'rmagan narsani qaytara olmaydi. Hech qachon add, commit yoki stash qilinmagan o'zgarish reset --hard, restore yoki checkout -- fayl dan keyin butunlay yo'qoladi. Bunday holatda yagona umid — VS Code'ning o'z tarixi (Timeline paneli) yoki muharrirda Ctrl + Z.
Bundan oddiy qoida chiqadi: tez-tez commit qiling. Commit qilingan narsa deyarli yo'qolmaydi. Commit qilinmagan narsa — himoyasiz.
12. Qancha vaqt saqlanadi? gc muddatlari
12.1 Uchta muddat
Yetim commitlar abadiy qolmaydi. Git vaqti-vaqti bilan "tozalash" — gc (garbage collection, axlat yig'ish) — o'tkazadi. U ko'plab buyruqlardan keyin avtomatik ishga tushadi (git gc --auto). git-scm.com hujjatidagi sukut qiymatlari:
| Sozlama | Sukut | Ma'nosi |
|---|---|---|
gc.reflogExpire |
90 kun | oddiy reflog yozuvlari shuncha saqlanadi |
gc.reflogExpireUnreachable |
30 kun | hozirgi tarixdan yetib bo'lmaydigan commitlarga oid yozuvlar |
gc.pruneExpire |
2 hafta | hech narsa ko'rsatmaydigan obyektlar o'chirilishidan oldingi muhlat |
Ya'ni reset --hard bilan "yo'qolgan" commit kamida 30 kun reflogda turadi. Reflogdan chiqqach, yana ikki hafta muhlat bor. Avtomatik gc esa har safar emas, faqat .git/objects da alohida (siqilmagan) obyektlar ko'payganda ishga tushadi (gc.auto — sukut bo'yicha 6700 ta). Amalda — bir necha hafta vaqtingiz bor.
Bu sozlamalar sizda o'rnatilmagan — sinovda git config gc.reflogExpire hech narsa chiqarmadi (chiqish kodi 1). Demak, sukut qiymatlari ishlaydi.
12.2 Majburiy tozalash — xavfli
Muddatlarni kutmasdan tozalash mumkin. Sinov repoda buni qilib ko'rdik — oqibatini ko'rish uchun:
git cat-file -t 91e0302
git reflog expire --expire-unreachable=now --all
git gc --prune=now --quiet
git cat-file -t 91e0302commit
fatal: git cat-file: could not get object infoTozalashdan oldin chegirma stashi bor edi (commit). Keyin — yo'q: "obyekt haqida ma'lumot olib bo'lmadi". Endi uni hech narsa qaytarmaydi.
Diqqat: Internetda "repo hajmini kamaytirish" uchun shu buyruqlar tavsiya qilinadi. Ularni favqulodda holatda — biror narsani qutqarmoqchi bo'lganingizda — hech qachon yozmang. Qutqaruv tugamaguncha
gcga tegmang.
12.3 Reflog — faqat sizniki
Reflog lokal. U GitHub'ga yuborilmaydi va git clone bilan kelmaydi. «Bahor» reposini nusxalab ko'rdik:
git clone -q bahor bahor-nusxa
cd bahor-nusxa
git reflog330abfe (HEAD -> main, origin/main, origin/HEAD) HEAD@{0}: clone: from C:/Users/.../kurs/bahor(Yo'lni ... bilan qisqartirdik.) Asl repoda yigirmadan ortiq yozuv bor edi, nusxada — bitta. Demak, hamkasbingizning kompyuterida yo'qolgan commitni sizning reflogingiz qutqarmaydi, va aksincha. git clone ni Remote darsida batafsil o'rganamiz.
13. Qaysi retsept? Xarita
flowchart TD
A["Nima yo'qoldi?"] --> B{"Commit qilinganmi?"}
B -- ha --> C{"Push qilinganmi?"}
C -- ha --> D["revert"]
C -- yo'q --> E["reflog → reset<br/>yoki branch"]
B -- yo'q --> F{"add yoki stash<br/>qilinganmi?"}
F -- ha --> G["fsck --lost-found"]
F -- yo'q --> H["Git'da yo'q:<br/>VS Code Timeline"]Nimaga qarang: birinchi savol doim bitta — "commit qilinganmi?". Chap tomondagi har qadam qutqarishni osonlashtiradi, o'ng tomonga o'tgan sari imkon kamayadi.
Maslahat: Xavfli buyruqdan oldin (katta
rebase,reset --hard, tarixni tozalash) bir soniyalik sug'urta qiling:git branch zaxira. Yorliq commitlarni ushlab turadi — reflogni qidirish ham kerak bo'lmaydi. Ish tugagach,git branch -D zaxira.
14. Ko'p uchraydigan xatolar
14.1 PowerShell'da HEAD@{1}
Git Bash'da hammasi ishlaydi. Lekin o'sha buyruqlarni Windows PowerShell'da (Windows'dagi standart 5.1 versiya) yozsangiz, sinovda shunday chiqdi:
git show --oneline --stat HEAD@{1}fatal: ambiguous argument 'HEAD@': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'Tarjimasi: "noaniq argument HEAD@: noma'lum reviziya yoki ishchi papkada yo'q yo'l". Git {1} ni umuman olmadi! git reset --hard HEAD@{1} esa yanada g'alati xato beradi — error: unknown switch `e' va uzun foydalanish yo'riqnomasi. Sabab: PowerShell'da jingalak qavslar — kod bloki. U {1} ni Git'ga matn sifatida bermaydi, o'rniga o'zining -encodedCommand ... argumentlarini qo'yib yuboradi. **Tuzatish:** bittalik qo'shtirnoq — git reset --hard 'HEAD@{1}' (sinovda git show --oneline -s 'HEAD@{1}' to'g'ri commitni ko'rsatdi) — yoki Git Bash ishlating. Kursda buyruqlar Git Bash uchun.
14.2 Raqam surilib ketdi
Aziz reflogni ko'rdi, keyin yana bir git switch qildi va git reset --hard HEAD@{1} yozdi. Lekin switch reflogga yangi yozuv qo'shdi — {1} endi boshqa narsani ko'rsatadi. Tuzatish: reflogdan SHA'ni nusxalang: git reset --hard d0dd8bb. SHA surilmaydi.
14.3 Qutqarayotib yangi ishni yo'qotish
Qutqarishda ishchi papkada saqlanmagan yangi o'zgarishlar bo'lsa, reset --hard ularni o'chiradi — yangi baxtsiz hodisa! Qutqarishdan oldin git status ga qarang. Toza bo'lmasa — avval git stash -u.
15. Mashqlar
1-mashq (oson): Reflogni o'qing
b09fa2a (HEAD -> main) HEAD@{0}: reset: moving to HEAD~3
3b4cb8f HEAD@{1}: commit: Menyu: somsa narxini qo'sh
07b061d (feature/dizayn) HEAD@{2}: checkout: moving from feature/dizayn to main- Oxirgi harakat nima bo'lgan?
- Reset'dan oldin HEAD qaysi commitda edi?
- Oxirgi holatga qaytish uchun qaysi buyruq?
Yechim
reset— HEAD uch commit orqaga surilgan.3b4cb8f— "Menyu: somsa narxini qo'sh".HEAD@{1}— bitta harakat oldin.git reset --hard 3b4cb8f(yokiHEAD@{1}, yoki darhol bo'lsaORIG_HEAD).
2-mashq (o'rta): Bo'sh joylarni to'ldiring
Aziz main da commit qildi, lekin bu fix/aloqa-manzil degan yangi branchda bo'lishi kerak edi. Commit hali yuborilmagan.
git fix/aloqa-manzil
git reset --hard
git log --oneline -1
git log --oneline -1 fix/aloqa-manzilIshora: yorliq qo'yadigan, lekin branchni almashtirmaydigan buyruq; main ni bitta commit orqaga surish (Reset va revert).
Yechim
git branch fix/aloqa-manzil
git reset --hard HEAD~1
git log --oneline -1
git log --oneline -1 fix/aloqa-manzilBirinchi log — main xato commitdan oldingi holatda. Ikkinchisi — xato commit endi fix/aloqa-manzil da. Tartibni almashtirmang: avval reset qilsangiz, commitni reflogdan qidirishga to'g'ri keladi.
3-mashq (qiyin): Uch baxtsiz hodisa
Har biri uchun retsept (buyruqlar ketma-ketligi) yozing va nega aynan shu ekanini tushuntiring:
- Sardor
git branch -D tolovqildi. Terminalni yopdi. Branchda 5 commit bor edi. - Sardor GitHub'ga yuborilgan
maindagi oxirgi commit saytni buzganini sezdi. - Sardor yangi
rasmlar.htmlnigit addqildi, keyingit stash dropo'rnigagit reset --hardyozdi.
Ishora: «Qaysi retsept? Xarita» diagrammasi, «O'chirilgan branchni tiklash», «Push qilingan xato» va «add qilingan, lekin commit qilinmagan fayl» retseptlari.
Yechim
git reflog—checkout: moving from tolov to ...qatorini topadi; undan oldingi yozuvning SHA'si — branch uchi.git branch tolov <sha>, keyingit log --oneline -5 tolovbilan tekshiradi. Branch o'z reflogi bilan birga o'chgan, shuning uchun HEAD reflogidan qidiriladi.git revert HEADva yangi commitni yuborish. Push qilingan commitniresetbilan olib tashlab bo'lmaydi — boshqalar tarixi buziladi.git fsck --lost-found→dangling blob <sha>→git show <sha>bilan mazmunini tekshiradi →git show <sha> > rasmlar.html.addfaylni blob qilib yozgani uchun qutqarish mumkin.addqilinmaganda — imkon yo'q edi.
4-mashq: Portfolio qadami — xavfsiz mashq
Portfolio'ingizda qutqarishni xavfsiz sinab ko'ring: vaqtinchalik branchda, haqiqiy ishga tegmasdan.
git switch -c chore/qutqarish-sinovva bitta sinov qatori bilan commit qiling.git reset --hard HEAD~1— commit "yo'qoldi".git reflog -3bilan uni toping va qaytaring.mainga qaytib,git branch -D chore/qutqarish-sinovbilan branchni o'chiring. Reflogdan branchni qayta tiklang.- Oxirida branchni butunlay o'chiring.
mainga hech narsa tegmaganinigit log --onelinebilan tekshiring.
Yechim
cd ~/kurs/portfolio
git switch -c chore/qutqarish-sinov
echo '<p>Sinov</p>' >> sayt/index.html
git add sayt/index.html
git commit -m "Sinov: vaqtinchalik qator qo'sh"
git reset --hard HEAD~1
git reflog -3
git reset --hard HEAD@{1}
git switch main
git branch -D chore/qutqarish-sinov
git reflog -1
git branch chore/qutqarish-sinov HEAD@{1}
git log --oneline -1 chore/qutqarish-sinov
git branch -D chore/qutqarish-sinov
git log --onelineBiz qisqa portfolio nusxasida sinadik. Reset'dan keyingi git reflog -3:
1aaefc2 (HEAD -> chore/qutqarish-sinov, main) HEAD@{0}: reset: moving to HEAD~1
33fd86f HEAD@{1}: commit: Sinov: vaqtinchalik qator qo'sh
1aaefc2 (HEAD -> chore/qutqarish-sinov, main) HEAD@{2}: checkout: moving from main to chore/qutqarish-sinovBranch o'chirilgach, git reflog -1 — checkout: moving from chore/qutqarish-sinov to main, demak HEAD@{1} — branch uchi. Tiklangan branch 33fd86f Sinov: vaqtinchalik qator qo'sh ni ko'rsatadi, oxirgi git log --oneline esa faqat ikki main commitini (1aaefc2 Bosh sahifa: footer qo'sh va 63190c1 Portfolio: 06-qism oxiridagi holat). SHA'lar sizda boshqacha. Bu mashqni bir marta qo'lingiz bilan qilgan bo'lsangiz, haqiqiy baxtsiz hodisada vahima qilmaysiz.
16. Real ishda
- Har bir tajribali dasturchi kamida bir marta reflog bilan "hayotini saqlab qolgan". Katta rebase buzilganda, noto'g'ri branch o'chirilganda — birinchi buyruq
git reflog. - "Oh Shit, Git!?!" — shunday retseptlar to'plamiga bag'ishlangan mashhur sayt (ohshitgit.com). Retseptlarning ko'pi aynan shu darsdagi buyruqlarga tayanadi.
- Jamoada: push qilingan tarixni
reset+ majburiy push bilan "tuzatish" — jiddiy xato hisoblanadi. Umumiy branchda — faqatrevert. Majburiy push va uning xavfsiz shaklini Ajralgan tarix darsida ko'rasiz. - Intervyuda: "
reset --hardqilib yubordim, commitni qanday qaytaraman?" — klassik savol. Javob:git reflog, SHA'ni topish,git reset --hard <sha>.
Xulosa
git reflog— HEAD harakatlari kundaligi;HEAD@{n}— n ta harakat oldingi holat. SHA — ishonchliroq.reset --hard,merge,amenddan qaytish: reflogdan SHA →reset(--hardyoki--soft); darhol bo'lsa —ORIG_HEAD.- O'chirilgan branch: HEAD reflogidan uchini topib,
git branch <nom> <sha>. - Noto'g'ri branchdagi commit:
git branch(yokicherry-pick) +reset --hard HEAD~1; push qilingan xato — faqatrevert. - Yo'qolgan stash va
addqilingan fayl —git fsck --lost-found; hech qachonaddqilinmagan o'zgarish qaytmaydi. - Sukut muddatlari: reflog 90 kun, yetib bo'lmaydigan yozuvlar 30 kun, yetim obyektlar yana 2 hafta; reflog lokal.
Keyingi dars: Worktree: bitta repoda parallel ishlash — stash qilmasdan, boshqa branchni alohida papkada ochib, ikki ishni bir vaqtda olib borishni o'rganamiz.
Manbalar
- Git hujjati: "git-reflog", "git-fsck", "git-gc" va
gc.*sozlamalari — git-scm.com/docs - Pro Git kitobi: "Git Internals — Maintenance and Data Recovery" — git-scm.com/book
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!