git revert — commitni bekor qilish, reset dan farqi
Muammodan boshlaylik
Juma, 17:00. Yangi to'lov moduli main ga qo'shildi va production ga deploy qilindi. 17:15 — mijozlar to'lov qila olmayapti. Xato tezda topilmaydi.
Kodni darhol oldingi holatga qaytarish kerak. Lekin:
git reset— push qilingan tarixni o'chiradi, hamkasblar tarixini buzadi (27-dars)- Qo'lda kodni tiklash — sekin va xatoga moyil
Yechim — git revert: tarixni o'chirmasdan, o'zgarishni bekor qiluvchi yangi commit yaratish.
Revert nima qiladi
git revert a3f9c2b
Git a3f9c2b commit idagi o'zgarishlarning teskarisini hisoblab, yangi commit yaratadi:
Commit a3f9c2b: Revert commit:
+ payme.yarat(summa) - payme.yarat(summa)
- click.yarat(summa) + click.yarat(summa)
Oldin: ●────●────A────B main
Keyin: ●────●────A────B────A̅ main
↑
"Revert 'To'lov: Payme integratsiyasi'"
A hali ham tarixda. A̅ — uni bekor qiladi. Natijada kod A dan oldingi holatda (B ning o'zgarishlari saqlangan holda).
Muharrir ochiladi, standart xabar:
Revert "To'lov: Payme integratsiyasi"
This reverts commit a3f9c2b8e1d4f6a7b9c0d2e4f6a8b0c2d4e6f8a0.
Sababini qo'shish yaxshi amaliyot: "Production da to'lovlar o'tmayapti, #91".
git push # oddiy push — hech qanday force kerak emas
Reset va revert — farqi
RESET (tarixni qayta yozadi): REVERT (tarixga qo'shadi):
●──●──A──B → ●──● ●──●──A──B → ●──●──A──B──B̅
git reset |
git revert |
|
|---|---|---|
| Tarix | Commitlarni olib tashlaydi | Yangi commit qo'shadi |
| Push qilingan commitlar | ❌ Xavfli (force kerak) | ✅ Xavfsiz (oddiy push) |
| Hamkasblarga ta'siri | Tarixlari buziladi | Hech qanday — oddiy pull |
| "Nima bo'lgan" izi | Yo'qoladi | Saqlanadi: xato va bekor qilish ko'rinadi |
| Qachon | Lokal, push qilinmagan | Ommaviy branch lar, production |
Qoida: push qilinganmi? → revert. Faqat lokalmi? → reset.
Bir nechta commit ni bekor qilish
git revert a3f9c2b e5f6a7b # ikkita — har biri uchun alohida revert commit
git revert HEAD~3..HEAD # oxirgi 3 ta
git revert --no-commit HEAD~3..HEAD # hammasini bitta revert commit ga
git commit -m "Revert: to'lov moduli o'zgarishlari (#91)"
--no-commit (-n) — o'zgarishlarni staging ga qo'yadi, commit qilmaydi: bir nechta revert ni bitta commit ga birlashtirish uchun.
Merge commit ni bekor qilish
Butun feature main ga merge commit bilan qo'shilgan (15-dars). Butun funksiyani bekor qilish:
git revert -m 1 9f8e7d6
Merge commit ning ikkita otasi bor. -m 1 — "birinchi otaga (main) nisbatan bekor qil", ya'ni feature branch dan kelgan hamma narsani olib tashla.
Bu --no-ff merge larning afzalligi (15-dars): butun funksiya — bitta revert. Squash merge da esa — bitta oddiy commit, -m siz revert.
[!WARNING] Merge commit revert qilingandan keyin, o'sha branch ni qayta merge qilsangiz — Git "bu commitlar allaqachon qo'shilgan" deb hisoblaydi va o'zgarishlar qaytmaydi. Funksiyani qaytarish uchun — revert ni revert qiling:
git revert <revert-commit-hash>.
Revert conflict
Bekor qilinayotgan commit dan keyin o'sha qatorlar yana o'zgargan bo'lsa — conflict:
CONFLICT (content): Merge conflict in src/tolov.js
error: could not revert a3f9c2b... To'lov: Payme integratsiyasi
Hal qilish — 16-dars kabi:
# tahrirlash → git add src/tolov.js
git revert --continue
# yoki
git revert --abort
Production da tez qaytarish — ish oqimi
git switch main
git pull
git log --oneline -10 # muammoli commit ni topish
git revert a3f9c2b # bekor qilish
npm test # tekshirish
git push # CI/CD avtomatik deploy qiladi
Sayt ishlaydi. Endi xotirjam, alohida branch da xatoni topib tuzatasiz va funksiyani qayta qo'shasiz.
[!TIP] Juma kechqurun xatoni tuzatishga urinmang — avval revert, sayt ishlasin. Tuzatish — dushanba kuni, xotirjam. "Roll back first, debug later" — production qoidasi.
Nima uchun shunday?
Nima uchun revert ataylab "xato + bekor qilish" ni tarixda qoldiradi — toza tarix yaxshiroq emasmi?
Chunki ommaviy tarix — jamoaviy kelishuv. Hamkasblaringizning lokal nusxalari, CI tizimi, deploy qilingan versiyalar, PR va issue havolalari — hammasi mavjud commit hash lariga tayanadi. Ularni o'chirish (reset + force) — bu kelishuvni bir tomonlama buzish. Revert esa tarixga faqat qo'shadi: hamma oddiy pull bilan sinxron bo'ladi, hech narsa buzilmaydi. Qo'shimcha foyda — halol hujjat: "bu funksiya 6-noyabrda chiqarildi, 15 daqiqadan keyin bekor qilindi, sabab — #91". Keyingi safar xuddi shu xatoga yo'l qo'ymaslik uchun aynan shunday tarix kerak.
Xulosa
Eslab qoling:
git revert <commit>— o'zgarishni bekor qiluvchi yangi commit- Tarix o'chirilmaydi; oddiy
git push— force kerak emas - Push qilingan → revert; lokal → reset
- Bir nechta:
git revert A ByokiHEAD~3..HEAD;--no-commit— bittaga - Merge commit:
git revert -m 1 <merge-hash> - Revert qilingan branch ni qayta qo'shish — revert ni revert qiling
- Conflict: tahrirlash →
git add→git revert --continue - Production da: avval revert, keyin xotirjam tuzatish
Keyingi dars
29-dars: git cherry-pick — boshqa branch dan bitta commit olish