Sari la conținut
← Git & GitHub pentru developeri
Progres curs 0 / 7 lecții (0%)

Recuperarea din greșeli

Lectură estimată: 5 minute

Estimare pentru text, la un ritm de 180 de cuvinte pe minut. Timpul pentru analizarea codului, exerciții și proiecte se adaugă separat și depinde de ritmul tău.

Lecția asta e cea la care te vei întoarce. Nu pentru că vei greși des, ci pentru că, atunci când se întâmplă, ai nevoie de răspunsul corect în treizeci de secunde, nu de o oră de căutat pe forumuri.

Principiul care te liniștește: în Git, aproape nimic din ce a fost commis nu se pierde definitiv. Chiar și după comenzi care par distructive, commit-urile rămân în baza de date locală zile întregi.

1. Am modificat un fișier și vreau să renunț

# un fișier
git restore src/config.js

# tot
git restore .

Atenție: modificările nesalvate se pierd definitiv. Git nu le-a văzut niciodată, deci nu le poate recupera.

2. Am dat git add din greșeală

git restore --staged fisier.txt

Scoate fișierul din staging, dar păstrează modificările în folder. Varianta veche, pe care o vei vedea în tutoriale, e git reset HEAD fisier.txt — face același lucru.

3. Am greșit mesajul ultimului commit

git commit --amend -m "Mesajul corect"

Doar dacă nu ai dat încă push. Dacă ai dat, vei avea nevoie de --force-with-lease și de acordul echipei.

4. Am uitat un fișier din ultimul commit

git add fisierul-uitat.php
git commit --amend --no-edit

5. Vreau să anulez ultimul commit, dar să păstrez modificările

git reset --soft HEAD~1

Commit-ul dispare, modificările rămân în staging, gata de recommit. Util când ai commis prea devreme sau ai amestecat două schimbări.

6. Vreau să șterg ultimul commit cu tot cu modificări

git reset --hard HEAD~1

Aici chiar pierzi munca necommisă. Înainte de orice --hard, obișnuiește-te să rulezi git status și, la nevoie, git stash -u.

Cele trei feluri de reset

git reset --soft  HEAD~1   # șterge commit-ul, păstrează modificările în staging
git reset --mixed HEAD~1   # șterge commit-ul, păstrează modificările nestaged (implicit)
git reset --hard  HEAD~1   # șterge commit-ul și modificările

7. Commit-ul e deja publicat și trebuie anulat

Aici nu folosești reset. Istoricul public nu se rescrie. Folosești revert, care creează un commit nou ce anulează efectul celui vechi:

git revert 8f3a1c2

E varianta corectă și sigură în producție: istoricul rămâne intact și se vede clar că a existat o problemă și că a fost anulată.

8. Am șters un branch din greșeală

Aici intervine eroul lecției: git reflog. El înregistrează toate mișcările lui HEAD, inclusiv cele „pierdute".

git reflog
9c1d2e3 HEAD@{0}: checkout: moving from feature/export to main
4b7e9a1 HEAD@{1}: commit: Adaugă generarea PDF
8f3a1c2 HEAD@{2}: commit: Structura inițială a exportului

Vezi hash-ul ultimului commit din branch-ul șters și îl recreezi:

git branch feature/export-recuperat 4b7e9a1

9. Am făcut reset --hard și vreau înapoi

Același reflog:

git reflog
git reset --hard HEAD@{1}

Atâta vreme ce commit-urile au existat, sunt recuperabile aproximativ 90 de zile, până la curățarea automată.

10. Am făcut push cu ceva ce nu trebuia

Dacă e vorba de cod greșit: git revert și push normal.

Dacă e vorba de un secret (parolă, cheie API): prima acțiune e să schimbi secretul, nu să cureți istoricul. Abia apoi cureți, cu git filter-repo sau BFG Repo-Cleaner, și anunți echipa că istoricul a fost rescris.

11. Nu știu ce se întâmplă, vreau starea curată de pe server

git fetch origin
git reset --hard origin/main
git clean -fd     # șterge fișierele untracked

Comanda asta aruncă tot ce ai local. Rulează întâi git status și git stash -u dacă ai vreun dubiu.

Cum afli ce commit a stricat ceva

Când o funcționalitate mergea acum o lună și azi nu mai merge:

git bisect start
git bisect bad                 # starea curentă e stricată
git bisect good 8f3a1c2        # aici mergea
# Git te plimbă prin commit-uri; la fiecare testezi și spui:
git bisect good    # sau: git bisect bad
git bisect reset

Prin căutare binară, găsești commit-ul vinovat în câțiva pași chiar și printre sute.

Util și pentru „cine a scris linia asta și de ce":

git blame -L 40,60 app/Services/FacturaService.php

Tabel de urgență

Renunț la modificări nesalvate     → git restore .
Scot din staging                   → git restore --staged fisier
Corectez ultimul commit            → git commit --amend
Anulez commit, păstrez modificări  → git reset --soft HEAD~1
Anulez commit publicat             → git revert <hash>
Recuperez orice                    → git reflog
Pun deoparte temporar              → git stash -u
Aflu ce a stricat                  → git bisect / git blame

Exercițiu

  1. Fă un commit, apoi git reset --hard HEAD~1. Recuperează-l folosind git reflog.
  2. Creează un branch, fă două commit-uri, șterge branch-ul cu -D și recreează-l din reflog.
  3. Fă un commit cu o greșeală evidentă, dă push, apoi anulează-l corect cu git revert.
  4. Scrie-ți propriul tabel de urgență și ține-l la îndemână.

Ai terminat cursul

Știi acum fluxul complet: repository, commit-uri curate, branch-uri, merge, rezolvarea conflictelor, rebase, pull requests și recuperarea din greșeli. Restul vine din repetiție — folosește Git pentru orice proiect, inclusiv notițe sau fișiere de configurare. În două săptămâni comenzile devin reflex.

Aplicație practică

Sarcina

Recuperează un commit folosind reflog într-un repository fictiv.

Rezolvare orientativă și verificare

Identifică hash-ul și creează un branch nou care îl păstrează. Pentru anularea publică preferă revert când este potrivit.

Greșeală de evitat

Nu experimenta cu reset --hard pe munca nesalvată.

Documentație și surse

Atelier final: Conflict de Git cu recuperare

Timp de lucru estimat: 40 de minute. Folosește datele de laborator de mai jos și salvează rezultatul separat de orice proiect real.

Date de pornire

Repository de laborator cu README. Branchul main schimbă instrucțiunea de instalare, branchul feature schimbă aceeași linie și adaugă un exemplu. Nu folosi un repository de producție.

1. Pregătire — 5 minute

Extrage intrările și condițiile din enunț. Notează ce rezultat trebuie produs și ce informații nu sunt confirmate. Pregătește fișierele sau tabelul în care vei păstra dovada lucrului.

2. Construire — 15 minute

Creează conflictul, citește ambele intenții și păstrează instrucțiunea corectă plus exemplul. Înregistrează commiturile, apoi exersează recuperarea unui commit pe un branch separat folosind reflog.

3. Variație și verificare — 15 minute

Prezintă diff-ul ca într-un pull request: problemă, soluție și verificare. Arată ce fișiere temporare trebuie excluse înainte de commit.

4. Autoevaluare — 5 minute

Compară rezultatul cu reperele de mai jos. Înregistrează cel puțin o eroare identificată sau un caz-limită verificat, plus corectura ori explicația comportamentului observat.

Repere de rezolvare

Conflictul este rezolvat fără marcaje rămase și fără pierderea exemplului. Commitul recuperat este referit de un branch. Istoricul partajat nu este rescris pentru a simplifica exercițiul.

Ce predai

  • Repository
  • Branch
  • Conflict rezolvat
  • Pull request
  • Exercițiu reflog

Criterii de acceptare

  • Nu sunt secrete în commit
  • Diff-ul este revizuit
  • Commitul recuperat este păstrat pe un branch

Păstrează o versiune inițială și una revizuită, cu explicația diferențelor. Dacă un criteriu nu este îndeplinit, revino la lecția relevantă și repetă verificarea. Durata este orientativă; instalarea mediului și aprofundarea pot necesita timp suplimentar.

Verifică-ți înțelegerea

5 întrebări · îți trebuie 70% ca să promovezi și ca lecția să fie marcată parcursă.

Autentifică-te ca să rezolvi testul și să-ți salvezi progresul.

Folosim cookie-uri esențiale pentru funcționarea site-ului și, cu acordul tău, cookie-uri de analiză și publicitate. Partenerii noștri, inclusiv Google, pot folosi cookie-uri pentru a afișa reclame relevante. Detalii în Politica de cookie-uri.