Un ghid pentru a anula greșelile cu Git (Partea a 2-a)
Publicat: 2022-03-10În această a doua parte a seriei noastre despre „Anularea greșelilor cu Git”, vom privi cu curaj din nou pericolul în ochi: am pregătit patru noi scenarii de apocalipsa – inclusiv, desigur, câteva modalități inteligente de a ne salva gâtul! Dar înainte de a ne arunca o privire: aruncați o privire la articolele anterioare despre Git pentru și mai multe metode de autosalvare care vă ajută să vă anulați greșelile cu Git!
Să mergem!
Recuperarea unei ramuri șterse folosind Reflog
Ai șters vreodată o ramură și, la scurt timp după, ți-ai dat seama că nu ar fi trebuit? În cazul improbabil în care nu cunoști acest sentiment, pot să-ți spun că nu este unul bun. Un amestec de tristețe și furie se strecoară asupra ta, în timp ce te gândești la toată munca grea care a intrat în comisiile acelei sucursale, la tot codul valoros pe care l-ai pierdut acum.
Din fericire, există o modalitate de a aduce acea ramură înapoi din morți - cu ajutorul unui instrument Git numit „Reflog”. Am folosit acest instrument în prima parte a seriei noastre, dar iată o mică reîmprospătare: Reflog-ul este ca un jurnal în care Git notează fiecare mișcare a indicatorului HEAD în depozitul tău local. Cu alte cuvinte, mai puțin tocilar: de fiecare dată când plătiți, comiteți, îmbinați, rebazați, alegeți și așa mai departe, este creată o intrare de jurnal. Acest lucru face din Reflog o plasă de siguranță perfectă atunci când lucrurile merg prost!
Să aruncăm o privire la un exemplu concret:
$ git branch * feature/login master
Putem vedea că în prezent avem feature/login
filialei verificate. Să presupunem că aceasta este ramura pe care o vom șterge (din neatenție). Înainte de a putea face asta, totuși, trebuie să trecem la o altă ramură, deoarece nu putem șterge ramura noastră HEAD actuală!
$ git checkout master $ git branch -d feature/login
Ramura noastră valoroasă a dispărut acum – și vă voi acorda un minut pentru (a) să înțelegeți gravitatea greșelii noastre și (b) să vă plângeți puțin. După ce ai șters lacrimile, trebuie să găsim o modalitate de a aduce înapoi această ramură! Să deschidem Reflog-ul (pur și simplu tastând git reflog
) și să vedem ce ne rezervă:
Iată câteva comentarii pentru a vă ajuta să înțelegeți rezultatul:
- În primul rând, trebuie să știți că Reflog-ul își sortează intrările cronologic: cele mai noi articole sunt în fruntea listei.
- Cel mai de sus (și, prin urmare, cel mai nou) element este comanda
git checkout
pe care am efectuat-o înainte de a șterge ramura. Este înregistrat aici în Reflog, deoarece este una dintre aceste „mișcări HEAD pointer” pe care Reflog le înregistrează cu atâta grijă. - Pentru a remedia greșeala noastră gravă, ne putem întoarce pur și simplu la starea anterioară - care este, de asemenea, consemnată în mod curat și clar în Reflog!
Deci, să încercăm asta, creând o nouă ramură (cu numele ramurii noastre „pierdute”) care începe la această stare „înainte” SHA-1:
$ git branch feature/login 776f8ca
Și voila! Veți fi încântați să vedeți că acum am restaurat ramura noastră aparent pierdută!
Dacă utilizați o interfață grafică pentru desktop Git, cum ar fi „Tower”, puteți lua o comandă rapidă frumoasă: apăsați pur și simplu CMD + Z de pe tastatură pentru a anula ultima comandă - chiar dacă tocmai ați șters violent o ramură!
Mutarea unui angajament într-o ramură diferită
În multe echipe, există un acord de a nu se angaja în ramuri de lungă durată, cum ar fi main
sau develop
: ramurile ca acestea ar trebui să primească noi comiteri numai prin integrări (de exemplu, fuziuni sau rebaze). Și totuși, desigur, greșelile sunt inevitabile: uneori uităm și ne comităm totuși în aceste ramuri! Deci, cum putem curăța mizeria pe care am făcut-o?
Din fericire, aceste tipuri de probleme pot fi corectate cu ușurință. Să ne suflecăm mânecile și să trecem la treabă.
Primul pas este să comutați la ramura de destinație corectă și apoi să mutați commit-ul folosind comanda cherry-pick
:
$ git checkout feature/login $ git cherry-pick 776f8caf
Veți avea acum commit-ul pe ramura dorită, unde ar fi trebuit să fie în primul rând. Minunat!
Dar mai rămâne un lucru de făcut: trebuie să curățăm creanga unde a aterizat accidental la început! Comanda cherry-pick
, ca să spunem așa, a creat o copie a commit-ului - dar originalul este încă prezent pe ramura noastră de lungă durată:
Aceasta înseamnă că trebuie să revenim la ramura noastră de lungă durată și să folosim git reset
pentru a o elimina:
$ git checkout main $ git reset --hard HEAD~1
După cum puteți vedea, folosim aici comanda git reset
pentru a șterge comiterea defectuoasă. Parametrul HEAD~1
îi spune lui Git să „retoarcă cu 1 revizuire în spatele HEAD”, ștergând efectiv cel mai de sus (și în cazul nostru: nedorit) din istoria acelei ramuri.
Și voilà: commit-ul este acum acolo unde ar fi trebuit să fie în primul rând și ramura noastră de lungă durată este curată - de parcă greșeala noastră nu s-ar fi întâmplat niciodată!
Editarea mesajului unui vechi commit
Este prea ușor să introduci o greșeală de tipar într-un mesaj de confirmare - și să o descoperi mult mai târziu. Într-un astfel de caz, vechea opțiune --amend
a git commit
nu poate fi folosită pentru a remedia această problemă, deoarece funcționează doar pentru ultima comitere. Pentru a corecta orice comitere mai veche decât aceasta, trebuie să apelăm la un instrument Git numit „Interactive Rebase”.
În primul rând, trebuie să spunem Interactive Rebase care parte din istoricul de comitere vrem să edităm. Acest lucru se face prin introducerea unui commit hash: commit-ul părinte al celui pe care vrem să-l manipulăm.
$ git rebase -i 6bcf266b
Se va deschide apoi o fereastră de editor. Conține o listă a tuturor comiterilor după cea pe care am furnizat-o ca bază pentru Rebase interactivă în comandă:
Aici, este important să nu urmezi primul impuls: în acest pas, încă nu edităm mesajul de comit. În schimb, îi spunem lui Git doar ce fel de manipulare vrem să facem cu ce comite(e). Destul de convenabil, există o listă de cuvinte cheie de acțiune notate în comentariile din partea de jos a acestei ferestre. Pentru cazul nostru, marcam linia #1 cu reword
(inlocuind astfel pick
standard).
Tot ce mai rămâne de făcut în acest pas este să salvați și să închideți fereastra editorului. În schimb, se va deschide o nouă fereastră de editor care conține mesajul curent al commit-ului pe care l-am marcat. Și acum este în sfârșit momentul să ne facem modificările!
Iată întregul proces dintr-o privire pentru tine:
Corectarea unui commit întrerupt (într-un mod foarte elegant)
În cele din urmă, vom arunca o privire la fixup
, cuțitul elvețian al instrumentelor de anulare. Mai simplu, vă permite să remediați o comitere ruptă/incompletă/incorectă după fapt. Este cu adevărat un instrument minunat din două motive:
- Nu contează care este problema.
Este posibil să fi uitat să adăugați un fișier, ar fi trebuit să ștergeți ceva, să fi făcut o modificare incorectă sau pur și simplu o greșeală de scriere.fixup
funcționează în toate aceste situații! - Este extrem de elegant.
Reacția noastră normală, instinctivă, la o eroare într-o comitere este să producem un nou comit care să rezolve problema. Acest mod de lucru, oricât de intuitiv ar părea, face ca istoricul de comitere să pară foarte haotic, foarte curând. Aveți comiteri „originale” și apoi aceste mici comiteri „aparate” care remediază lucrurile care au mers prost în comiterile originale. Istoria ta este plină de comiteri mici, fără sens, ceea ce face dificil de înțeles ce s-a întâmplat în baza ta de cod.
Aici intervine fixup
. Vă permite să faceți în continuare această comitere de corectare. Dar aici vine magia: apoi îl aplică la comiterea originală, ruptă (reparându-l în acest fel) și apoi aruncă complet comiterea urâtă de band-aid!
Putem trece printr-un exemplu practic împreună! Să presupunem că commit-ul selectat aici este rupt.
Să mai spunem că am pregătit modificări într-un fișier numit error.html
care vor rezolva problema. Iată primul pas pe care trebuie să-l facem:
$ git add error.html $ git commit --fixup 2b504bee
Creăm un nou commit, dar îi spunem lui Git că acesta este unul special: este o remediere pentru un vechi commit cu hash-ul SHA-1 specificat ( 2b504bee
în acest caz).
Al doilea pas, acum, este să porniți o sesiune Interactive Rebase - deoarece fixup
aparține setului mare de instrumente Interactive Rebase.
$ git rebase -i --autosquash 0023cddd
Două lucruri merită explicate despre această comandă. În primul rând, de ce am furnizat 0023cddd
ca hash de revizuire? Pentru că trebuie să începem sesiunea noastră interactivă Rebase la comiterea părintelui colegului nostru defect.
În al doilea rând, pentru ce este opțiunea --autosquash
? Ne ia multă muncă de pe umeri! În fereastra editorului care se deschide acum, totul este deja pregătit pentru noi:
Datorită opțiunii --autosquash
, Git a făcut deja munca grea pentru noi:
- Acesta a marcat micul nostru angajament de band-aid cu cuvântul cheie de acțiune
fixup
. În acest fel, Git îl va combina cu commit-ul direct de mai sus și apoi îl va renunța. - De asemenea, a reordonat liniile în consecință, mutându-ne comiterea cu band-aid direct sub comiterea pe care vrem să-l reparăm (din nou:
fixup
funcționează combinând comiterea marcată cu cea de mai sus !).
Pe scurt: Nu e nimic de făcut pentru noi decât să închidem fereastra!
Să aruncăm o privire finală asupra rezultatului final.
- Commit-ul rupt anterior este remediat: acum conține modificările pe care le-am pregătit în commit-ul de band-aid.
- Comiterea urâtă a comiterii în sine a fost eliminată: istoricul comisiilor este curat și ușor de citit - ca și cum nu s-ar fi produs nicio greșeală.
A ști cum să anulezi greșelile este o superputere
Felicitări! Acum poți să-ți salvezi gâtul în multe situații dificile! Nu putem evita cu adevărat aceste situații: indiferent de cât de experimentați suntem ca dezvoltatori, greșelile sunt pur și simplu o parte din muncă. Dar acum că știi cum să le faci față, le poți face față cu o frecvență cardiacă relaxată.
Dacă doriți să aflați mai multe despre anularea greșelilor cu Git, vă pot recomanda „Trusa de prim ajutor pentru Git”, o serie de videoclipuri scurte despre exact acest subiect.
Distrează-te făcând greșeli – și, bineînțeles, anulându-le cu ușurință!