Kratak odgovor
Commit poništavate sa `git reset` ako izmena još nije otišla na udaljeni repozitorijum, ili sa `git revert` ako je već podeljena sa drugima. Pre bilo čega proverite `git status` i `git log`, jer `git reset --hard` trajno briše nepokomitovane izmene u praćenim fajlovima.
Kako se problem prepoznaje
- Napravili ste commit sa pogrešnim fajlovima ili porukom
- Poslednji commit je pokvario build ili testove
- Commit je već gurnut na udaljeni repozitorijum pa ne znate kako da ga uklonite
- Slučajno ste izvršili `git reset --hard` i izgubili izmene
- Radno stablo je u čudnom stanju posle neuspešnog reset-a
Najčešći uzroci
Pogrešan sadržaj commita
U commit su ušli fajlovi koji ne treba da budu tu, poput `.env` fajla ili izmena iz druge grane.
Commit sa greškom u kodu
Izmena je prošla lokalno, ali ruši testove ili aplikaciju, pa je potrebno vratiti prethodnu verziju.
Commit je već podeljen
Ako je commit gurnut na `main` granu koju koriste i drugi, prepisivanje istorije pravi probleme saradnicima.
Nerazumevanje reset opcija
`--soft`, `--mixed` i `--hard` različito tretiraju indeks i radni direktorijum, pa se lako izgube izmene.
Rešenje korak po korak
- 1
Proverite trenutno stanje repozitorijuma
Pokrenite
git statusda vidite da li ima nepokomitovanih izmena igit log --oneline -5da vidite poslednjih pet commita. Zapišite hash commita na koji želite da se vratite, jer će vam trebati u koracima koji slede. Ako ima nepokomitovanog rada, prvo ga sačuvajte sagit stash. - 2
Sačuvajte rezervnu kopiju grane
Pre bilo kakvog reset-a napravite granu koja pokazuje na trenutno stanje:
git branch backup-<ime>. Tako možete da se vratite na staro stanje ako nešto pođe naopako. Ova grana ne smeta i možete je obrisati kasnije sagit branch -D backup-<ime>. - 3
Poništite poslednji commit bez brisanja izmena
Ako želite da commit nestane, a izmene ostanu u radnom direktorijumu, koristite
git reset --soft HEAD~1. Fajlovi ostaju izmenjeni i spremni za novi, ispravan commit. Ovo je najbezbednija opcija za lokalni rad. - 4
Vratite indeks i radni direktorijum na prethodni commit
Za potpuno vraćanje na prethodno stanje koristite
git reset --hard HEAD~1. Upozorenje: ova komanda uklanja poslednji commit sa trenutne grane i trajno briše sve nepokomitovane izmene u praćenim fajlovima. Prvo proveritegit statusi napravite rezervnu granu. - 5
Vratite se na konkretan commit po hash-u
Ako ne vraćate samo poslednji commit, navedite hash:
git reset --hard <hash>. Hash pronađite ugit log --oneline. Za više commita unazad koristiteHEAD~3umesto hash-a. I ovde važi upozorenje: prvo napravite rezervnu granu i proveritegit status, jer ova komanda briše nepokomitovane izmene u praćenim fajlovima. - 6
Poništite commit koji je već gurnut
Ako je commit već na udaljenom repozitorijumu, nemojte koristiti
resetna deljenoj grani. Umesto toga pokrenitegit revert <hash>, koji pravi novi commit sa suprotnim izmenama. Zatim gurnite sagit push. - 7
Vratite izgubljene commit-e iz reflog-a
Ako ste slučajno izvršili
reset --hardi izgubili commit, pokrenitegit reflogi pronađite hash stanja pre reset-a. Zatim se vratite sagit reset --hard <hash>, ali prvo proveritegit statusjer i ova komanda briše nepokomitovane izmene u praćenim fajlovima. Reflog čuva istoriju pokazivača HEAD obično 30 do 90 dana, ali ne može da vrati nepokomitovane izmene. - 8
Proverite rezultat i nastavite rad
Pokrenite
git statusigit log --oneline -3da potvrdite da je stanje ispravno. Ako ste radilirevert, proverite da li je novi commit prisutan. Tek kada ste sigurni, obrišite rezervnu granu.
Kada reset nije dovoljan
Ako je pogrešan commit već otišao na deljenu granu i drugi su ga povukli, git revert je najbezbedniji put. Nasilno guranje prepisane istorije sa git push --force na deljenoj grani može da obriše tuđe commite i izazove konflikte kod svih saradnika. Ako morate da izvršite force push, prvo obavestite tim i koristite --force-with-lease umesto --force, jer se ta komanda zaustavlja ako je neko u međuvremenu gurnuo izmene. Za velike fajlove ili tajne ključeve koji su ušli u istoriju, reset nije dovoljan: potrebno je čišćenje istorije i rotacija ključeva.
Kako da sprečite da se ponovi
- Commit-ujte često i u malim celinama, sa jasnom porukom
- Pre `reset --hard` uvek proverite `git status` i napravite rezervnu granu
- Koristite `git revert` na deljenim granama, a `reset` samo lokalno
- Redovno gurnite rad na udaljeni repozitorijum da ne zavisi samo od lokalnog stanja
Kada je bolje pozvati stručnjaka
Ako je pogrešan commit već na deljenoj grani koju koristi više ljudi, ili ako niste sigurni šta će reset uraditi sa vašim nepokomitovanim radom, bolje je da se posavetujete sa IT podrškom pre nego što nastavite sami.
Razvoj softvera i proizvoda · Aplikacije po meri, SaaS i MVP za 4 do 8 nedeljaČesta pitanja
Koja je razlika između git reset i git revert?
`git reset` pomera pokazivač grane i prepisuje istoriju, pa je bezbedan samo lokalno. `git revert` pravi novi commit koji poništava prethodni i ne menja istoriju, pa je siguran za deljene grane.
Da li mogu da vratim commit koji sam slučajno obrisao?
Možete, ako ga pronađete u `git reflog`. Pokrenite `git reflog`, pronađite hash željenog stanja i vratite se sa `git reset --hard <hash>`.
Šta znači --soft, --mixed i --hard kod git reset?
`--soft` zadržava izmene u indeksu i radnom direktorijumu, `--mixed` (podrazumevano) zadržava izmene samo u radnom direktorijumu, a `--hard` briše izmene u praćenim fajlovima i vraća ih na stanje commita.