Până acum am analizat scenariul ideal: scrieți cod, creați commit-uri și deschideți Pull Request-uri. În practică însă, lucrurile nu merg mereu conform planului: uitați să adăugați un fișier, faceți o greșeală de scriere în mesajul commit-ului sau vă dați seama că ați luat-o într-o direcție greșită. În acest articol vedem cum puteți rezolva cele mai frecvente probleme cu instrumentele IDE.

Exemplele și capturile de ecran sunt din IDE-urile JetBrains; denumirile și amplasarea acțiunilor pot fi diferite în versiunea dumneavoastră. Pentru exerciții, folosiți un repository separat, de test. Într-un proiect de lucru, respectați regulile acestuia pentru ramuri, commit-uri și trimiterea modificărilor.

Când Claude Code lucrează în proiect, istoricul salvat vă ajută să reveniți la o stare anterioară. Dar Git nu înregistrează fiecare apăsare de tastă: modificările fără commit se pot pierde. Înainte să anulați ceva, verificați ramura, fișierele selectate și dacă aveți copia necesară.

Rollback - anularea modificărilor locale

Scenariu: ați modificat un fișier, apoi ați observat că toate schimbările sunt greșite și vreți să-l readuceți rapid la starea din ultimul commit.

Ilustrație pentru secțiunea "Rollback - anularea modificărilor locale"

Folosiți funcția Rollback:

  1. deschideți fila Commit din panoul din stânga;
  2. găsiți în listă fișierul modificat (sau selectați mai multe) pe care vreți să-l readuceți la starea anterioară;
  3. faceți clic dreapta și alegeți Rollback (sau apăsați pictograma cu săgeata rotunjită).

IDE-ul vă va avertiza că modificările locale selectate se vor pierde. Mai întâi consultați diff-ul și salvați ce vă trebuie. Confirmați Rollback doar pentru schimbările pe care chiar vreți să le eliminați, apoi verificați rezultatul. Operația șterge lucrul fără commit, nu face o copie de rezervă.

De reținut

Înainte de Rollback, separați modificările agentului de schimbările anterioare din același fișier. Rollback readuce fișierele selectate la starea ultimului commit (HEAD) și elimină atât modificările pregătite, cât și pe cele nepregătite. Nu este același lucru cu git restore fără flag-uri: acesta preia conținutul din index și modifică doar fișierele de lucru.

Amend - completați ultimul commit

Scenariu: tocmai ați apăsat Commit și v-ați dat seama imediat că ați uitat să atașați un fișier important (de exemplu, un test actualizat) sau că ați greșit în mesaj. Dacă commit-ul nu a fost încă publicat, puteți folosi Amend. Un commit separat de corectare este și el acceptabil, mai ales într-un istoric deja partajat.

Ilustrație pentru secțiunea "Amend - completați ultimul commit"

Pentru a completa un commit nepublicat, folosiți funcția Amend (a completa/a corecta):

  1. în fereastra Commit, faceți modificările în fișierul uitat și bifați căsuța din dreptul lui;
  2. în panoul Commit Message, găsiți caseta de selectare Amend (sau pictograma rotiței -> Amend Commit) și bifați-o;
  3. IDE-ul va prelua mesajul commit-ului anterior, pe care îl puteți edita;
  4. apăsați Commit.

Amend creează un commit nou în locul celui vechi, cu un alt identificator. Obiectul vechi nu este editat pe loc. Dacă acel commit a fost deja trimis și este folosit de alții, de obicei e mai bine să faceți o corectare separată.

Aflați mai multe despre această funcție în tutorialul oficial JetBrains.

Undo Commit

Scenariu: ați creat un commit, dar încă nu l-ați trimis prin Push și v-ați dat seama că v-ați grăbit. Vreți ca commit-ul să dispară din istoric, dar modificările să rămână în editor ca să puteți continua lucrul.

Folosiți funcția Undo Commit:

  1. deschideți istoricul - fila Git -> Log din partea de jos;
  2. găsiți ultimul commit din ramura curentă (HEAD), nu pur și simplu primul rând din graful comun, apoi deschideți meniul contextual al acestuia;
  3. alegeți Undo Commit.
Ilustrație pentru secțiunea "Undo Commit"

Selectați lista de modificări (de obicei Default Changelist) și apăsați OK. Commit-ul va dispărea din istoric, iar fișierele vor reveni în fereastra Commit marcate ca modificate. N-ați pierdut nimic și puteți continua lucrul fără griji.

Reset - mutarea ramurii și starea fișierelor

Funcția Reset Current Branch to Here... este un instrument puternic, care mută indicatorul ramurii dumneavoastră la orice commit selectat. În funcție de situație, poate anula delicat ultimele acțiuni sau poate șterge radical codul defect.

Scenariul A - anularea ultimelor commit-uri locale

Ați creat local câteva commit-uri (înainte de Push) și v-ați dat seama că întreaga direcție de dezvoltare din această ramură a fost greșită.

  1. deschideți fila Git -> Log;
  2. găsiți ultimul commit bun la care vreți să reveniți (cel de dinaintea seriei de commit-uri greșite);
  3. faceți clic dreapta pe el și alegeți Reset Current Branch to Here....

Scenariul B - resetarea la starea de pe server

Vreți să recuperați fișierele urmărite conform ramurii remote. Mai întâi salvați lucrul local de care aveți nevoie și executați Fetch: eticheta origin/main reflectă ultima stare preluată, nu starea serverului actualizată continuu. Dacă există o operație cu conflicte în curs, rezolvați-o și finalizați-o sau anulați-o mai întâi; nu folosiți Hard ca remediu universal.

  1. deschideți Git -> Log;
  2. găsiți indicatorul ramurii remote - de obicei, este un commit cu eticheta mov origin/main (sau origin/numele_ramurii). Aceasta este ultima stare cunoscută a codului de pe server;
  3. faceți clic dreapta pe acel commit și alegeți Reset Current Branch to Here....
Fereastra Reset Current Branch

Modurile de resetare

Alegeți cu atenție modul din fereastra de resetare. În toate cele trei variante, ramura curentă se mută la commit-ul selectat, dar indexul și fișierele de lucru sunt tratate diferit:

  • Soft păstrează fișierele de lucru și indexul. Mixed păstrează fișierele de lucru, dar readuce indexul la commit-ul selectat: diferențele rămân nepregătite. Sunt moduri diferite, deși ambele vă permit să continuați lucrul cu conținutul fișierelor;
  • Hard aduce indexul și fișierele urmărite la starea commit-ului selectat, distrugând modificările lor fără commit. Fișierele untracked obișnuite, fără legătură, pot rămâne, iar căile care împiedică recuperarea pot fi șterse. Commit-urile nu dispar imediat din toate depozitele, dar nu contați pe o recuperare ulterioară a lucrului pierdut.

Ce faceți după push

Scenariu: ați făcut push și abia apoi ați observat o greșeală.

De îndată ce un commit ajunge pe server, devine parte din istoricul comun al proiectului. Încercarea de a rescrie acest istoric (prin Reset sau Amend) le poate crea probleme mari colegilor - gândiți-vă că ei au descărcat deja modificările dumneavoastră și au început să lucreze pornind de la ele.

Soluția corectă și sigură: creați pur și simplu un commit nou care corectează greșeala și trimiteți-l cu un push obișnuit. Este o practică normală. Un istoric liniar, în care după codul greșit urmează un commit de corectare ușor de înțeles, face evoluția proiectului transparentă pentru întreaga echipă.

IDE-ul are și o funcție specială, Revert Commit. Dacă faceți clic dreapta pe commit-ul greșit din jurnalul Git -> Log și alegeți Revert Commit, IDE-ul va crea un "anti-commit" nou, care face exact opusul celui greșit (de exemplu, șterge rândurile adăugate).

Ilustrație pentru secțiunea "Ce faceți după push"

Revert este util când vreți să anulați o modificare publicată printr-un commit nou. Se poate folosi atât pentru cod, cât și pentru text, dar poate intra în conflict cu modificările ulterioare. După rezolvarea conflictului, verificați rezultatul; când dependențele sunt complicate, uneori o corectare separată e mai clară.

Stash / Shelve - punerea temporară deoparte a modificărilor

Scenariu: lucrați intens la codul unei funcționalități noi și toate fișierele apar colorate în roșu și albastru. Deodată vine team lead-ul: "lasă totul, trebuie să reparăm urgent un bug în ramura main". Nu puteți trece la main, fiindcă aveți modificări nefinalizate care intră în conflict. Un commit local intermediar poate fi permis de regulile proiectului, dar dacă nu e momentul potrivit să înregistrați lucrul, îl puteți pune deoparte.

Soluția este să puneți temporar lucrul într-o cutie virtuală. În Git se numește Stash, iar IDE-ul are un mecanism separat, Shelve (a pune pe raft).

  1. deschideți fereastra Commit și selectați fișierele modificate;
  2. alegeți Shelve Changes...; acești pași se referă la Shelve, iar Git Stash se apelează separat;
  3. dați un nume ușor de recunoscut acestei intrări și apăsați Shelve.
Ilustrație pentru secțiunea "Stash / Shelve - punerea temporară deoparte a modificărilor"

După Shelve, verificați fișierele rămase: au fost puse deoparte toate modificările de care aveți nevoie? Acum puteți trece la main, corecta greșeala și salva rezultatul conform regulilor proiectului. Apoi reveniți la ramura de lucru, deschideți Shelf și alegeți Unshelve.

Pentru Git Stash, folosiți lista separată de stash-uri și recuperați intrarea necesară. Este un alt spațiu de stocare. Un stash obișnuit nu include fișierele untracked noi fără o opțiune suplimentară; înainte să schimbați ramura, verificați că tot lucrul necesar este salvat. Recuperarea poate genera conflicte, așa că verificați din nou fișierele după operație.

Lucrul cu istoricul, mai în detaliu

Fereastra Git -> Log nu este doar o listă de commit-uri, ci și un instrument puternic de investigare.

  • Hash-ul commit-ului este un șir de litere și cifre, de exemplu a1b2c3d. Identifică în mod unic fiecare instantaneu al codului dumneavoastră.Hash-ul commit-ului în jurnal
  • puteți filtra istoricul după ramură, autor, dată sau un cuvânt din mesajul commit-ului - astfel aflați rapid cine și când a lucrat la o anumită parte;
  • pentru a găsi commit-ul în care a fost adăugat sau șters un anumit rând de cod, fereastra Log permite căutarea nu doar în mesaje, ci și în conținutul modificărilor;
  • faceți clic dreapta în marginea editorului (unde apar numerele de rând) și alegeți Annotate with Git Blame - IDE-ul va arăta lângă fiecare rând cine l-a modificat ultima dată și în ce commit. Apoi deschideți commit-ul și discuția asociată: Blame indică ultima modificare a rândului, dar nu explică motivul.

Zonă periculoasă - Force Push

Am stabilit că modificarea commit-urilor deja trimise nu este o idee bună. Dar dacă totuși v-ați schimbat istoricul local (de exemplu, prin Undo Commit sau Amend), iar pe server se află încă versiunea veche? La un push obișnuit, Git va afișa o eroare pentru a proteja istoricul comun de rescriere.

Force push permite înlocuirea referinței remote selectate chiar și atunci când noul istoric nu continuă istoricul anterior. Nu curăță întregul server: consecințele depind de referințele trimise. Protecția ramurii poate bloca această trimitere.

Force push poate elimina din ramura remote commit-uri care nu există în istoricul local. De aceea, rescrierea unei ramuri comune necesită o decizie separată, agreată de echipă. Pentru o corectare obișnuită, folosiți un commit nou sau Revert.

Un caz tipic în care se discută despre force push este ramura proprie, după rescrierea convenită a istoricului ei. Chiar și atunci, verificați dacă au apărut commit-uri noi ale altcuiva. Varianta --force-with-lease verifică starea așteptată a ramurii remote, dar tot trebuie să înțelegeți ce commit-uri vor fi înlocuite.

În captură, Force Push se află în meniul derulant al butonului Push. Înainte să-l folosiți, verificați ce mod de trimitere forțată aplică versiunea IDE-ului dumneavoastră.

Butonul Force Push

Dacă nu sunteți siguri 100% ce faceți, nu folosiți force push. Este mai sigur să creați un commit nou cu corecturile (sau să folosiți Revert).

Legătura cu Claude Code

Regula este aceeași atât pentru dumneavoastră, cât și pentru Claude Code: rescrierea istoricului comun este periculoasă. Nu tratați force push ca pe ceva obișnuit și nu îl lăsați să fie executat pe ramuri comune. Dacă Claude propune ceva care ar rescrie istoricul de pe server, opriți-vă și verificați dacă există o alternativă sigură (un commit nou, Revert).

Actualizarea proiectului

Înainte de o sarcină nouă, verificați ramura de bază și modificările neterminate. Preluați actualizările când este cazul și analizați rezultatul îmbinării. Update Project nu garantează că nu vor apărea conflicte și, în funcție de setări, poate folosi merge sau rebase.

După actualizare, verificați ramura curentă, lista de commit-uri și starea fișierelor. Dacă apar conflicte, rezolvați-le înainte să continuați.

Meniul contextual Git Log

Când deschideți fila Git -> Log și faceți clic dreapta pe orice commit, apare un meniu contextual mare. Să trecem prin comenzile cele mai utile, grupate după scop.

Ilustrație pentru secțiunea "Meniul contextual Git Log"

Grupul 1 - vizualizare și analiză (acțiuni sigure)

  • Copy Revision Number - copiază hash-ul unic al commit-ului în clipboard. E util pentru a trimite colegului un link către commit sau pentru a-l menționa într-un tichet (Jira, YouTrack);
  • Compare with Local - compară starea fișierului dintr-un commit mai vechi cu cea din editorul dumneavoastră. O modalitate bună de a vedea cum arăta codul acum o lună;
  • Show Repository at Revision - deschide structura tuturor fișierelor proiectului așa cum era la momentul acelui commit (ramura curentă nu se schimbă).

Grupul 2 - lucrul cu ramurile

  • New Branch... - creează o ramură nouă pornind direct de la commit-ul selectat din trecut. Este utilă dacă ați avansat mult, ați realizat că ați stricat lucrurile și vreți să porniți o ramură nouă de la ultima stare funcțională;
  • Checkout Revision - trece proiectul local la acest commit. Veți ajunge în starea detached HEAD: puteți rula codul vechi, dar commit-urile noi nu vor aparține niciunei ramuri. Dacă ați creat commit-uri de care aveți nevoie în detached HEAD, salvați-le mai întâi într-o ramură nouă. Pentru a reveni, faceți Checkout pe o ramură obișnuită (de exemplu, main).

Grupul 3 - modificare și transfer

  • Cherry-Pick - vă permite să preluați un anumit commit din altă ramură și să-l copiați în cea curentă. De exemplu, cineva a corectat într-o altă ramură un bug care vă blochează lucrul; cu Cherry-Pick aduceți acel commit în ramura dumneavoastră, fără să îmbinați întreaga ramură a colegului;
  • Edit Commit Message... - dacă un commit nu a fost încă trimis (nu a avut loc Push), îi puteți schimba rapid mesajul. Este mai simplu decât Amend când vreți să modificați doar textul.

Grupul 4 - anularea modificărilor

Am discutat deja pe larg aceste comenzi:

  • Reset Current Branch to Here... - mută ramura curentă la acest commit (schimbând istoricul disponibil din ramură);
  • Revert Commit - creează un "anti-commit" care anulează conținutul modificat printr-un commit local nou, trimis apoi pe server;
  • Undo Commit... - readuce commit-ul local în fereastra de modificări.

Grupul 5 - rescrierea istoricului

Meniul include și comenzi precum Squash Commits... (combină mai multe commit-uri într-unul singur), Drop Commits (elimină un commit din mijlocul istoricului) sau Interactively Rebase from Here.... Sunt instrumente pentru intervenții chirurgicale fine în istoricul local (Interactive Rebase).

De reținut

Cât timp încă vă obișnuiți cu Git, încercați să nu folosiți aceste comenzi: pot rescrie commit-urile selectate și restul istoricului ramurii. În lucrul real în echipă, sunt folosite pentru a face ordine într-o ramură locală de ciornă înainte de review (crearea unui Pull Request).

Git - plasa dumneavoastră de siguranță

Alegeți metoda de recuperare în funcție de starea lucrului: fișierele fără commit, commit-urile locale și istoricul publicat necesită acțiuni diferite. E mai util să păstrați versiunea necesară și să consultați modificările înainte de operație decât să sperați că orice greșeală poate fi anulată.

Cum se integrează cu Claude Code

Când Claude Code lucrează în proiect, aceste instrumente sunt principala dumneavoastră protecție. Iată cum să le folosiți:

  • creați commit-uri des: fiecare commit este un punct la care puteți reveni. Dacă agentul o ia într-o direcție greșită, reveniți la ultima stare funcțională;
  • pentru a anula modificări fără commit, separați mai întâi schimbările necesare, apoi verificați ce fișiere sunt afectate și de unde se face recuperarea în Rollback sau git restore;
  • dacă ați creat deja commit-ul, dar nu l-ați trimis, Undo Commit readuce modificările în editor;
  • dacă eroarea a ajuns deja pe server, un commit nou cu o corectare sau Revert este mai sigur decât rescrierea istoricului.
De reținut

Nu acceptați fără să verificați acțiunile care șterg date sau rescriu istoricul (Reset hard, force push). Mai întâi vedeți ce urmează să facă Claude Code. Înainte de o sarcină amplă, salvați starea de care aveți nevoie și verificați că punctul de revenire chiar conține lucrul dumneavoastră.

Articolul anterior: Pull request-uri, de la creare la merge · Articolul următor: Crearea unui repository, rebase și secrete