Sună familiar? “Ajutor! M-am angajat în ramura greșită! ” „Sa întâmplat din nou … Unde este angajamentul meu?”

Ei bine, am fost de atâtea ori acolo. Cineva îmi cheamă numele pentru ajutor atunci când ceva nu merge bine git. Și s-a întâmplat nu numai când învățam studenți, ci și în timp ce lucram cu dezvoltatori experimentați.

În timp, am cam devenit „tipul Git”.

Folosim git tot timpul și, de obicei, ne ajută să facem treaba. Dar uneori, și mult mai des decât ne-am putea dori, lucrurile merg prost.

Poate că ne-am angajat în ramura greșită. Poate că am pierdut un cod pe care l-am scris. Poate că am comis ceva la care nu vrem.

Git Reset Explained Cum se salveaza ziua cu comanda
Sursa: xkcd.com

Există multe resurse online despre git, iar unii dintre ei (ca acesta) se concentrează de fapt asupra a ceea ce se întâmplă în aceste scenarii nedorite.

Dar întotdeauna am simțit că acestor resurse le lipsește „De ce” . Când este prevăzută cu un set de comenzi, ce face fiecare comandă? Și cum ați ajuns la aceste comenzi în primul rând? ?

În o postare anterioară, am oferit o introducere vizuală la internele Git. În timp ce înțelege internele git este util, obținerea teoriei este aproape niciodată suficientă. Cum ne aplicăm cunoștințele despre gitInternele și îl folosim pentru a remedia problemele în care ne-am prins?

În această postare, aș dori să elimin acest decalaj și să detaliez pe git reset comanda. Vom ajunge să înțelegem ce git reset face în culise și apoi aplică aceste cunoștințe pentru a rezolva diferite scenarii. ?

Temeiuri comune – director de lucru, index și depozit

Pentru a înțelege mecanismele interioare ale git reset, este important să înțelegeți procesul de înregistrare a modificărilor din interior git . Mai exact, mă refer la dir. de lucru, index, si repertoriu.

Dacă aveți încredere în acești termeni, nu ezitați să treceți la următoarea secțiune. Dacă doriți o explicație și mai profundă, vedeți aceasta postarea anterioară.

Când lucrăm la codul sursă, lucrăm de la direcție de lucru – orice director din sistemul nostru de fișiere care are un repertoriuasociat cu acesta. Acesta conține folderele și fișierele proiectului nostru, precum și un director numit .git.

După ce facem unele modificări, dorim să le înregistrăm în repertoriu . A repertoriu (repope scurt) este o colecție de comite , fiecare dintre ele fiind o arhivă a ceea ce este proiectul copac de lucru arăta ca la o întâlnire anterioară, fie pe aparatul nostru, fie al altcuiva.

1611618247 341 Git Reset Explained Cum se salveaza ziua cu comanda

Să creăm un fișier în directorul de lucru și să rulăm git status:

1611618247 237 Git Reset Explained Cum se salveaza ziua cu comanda

Inca, gitnu comite modificări de la copac de lucrudirect în repertoriu.

În schimb, modificările sunt înregistrate mai întâi în ceva numit index, sau zona de punere în scenă. Ambii termeni se referă la același lucru și sunt folosiți adesea în git documentația. Vom folosi acești termeni în mod interschimbabil pe parcursul acestei postări.

Când folosim git add, adăugăm fișiere (sau modificări în fișiere) la zona de punere în scenă . Să folosim această comandă pe fișierul pe care l-am creat mai devreme:

1611618247 526 Git Reset Explained Cum se salveaza ziua cu comanda

La fel de git status dezvăluie, fișierul nostru este pus în scenă(și gata „să fie angajat”). Cu toate acestea, nu face parte din niciunul comite. Cu alte cuvinte, este acum în dir. de lucru, la fel de bine ca index, dar nu în repertoriu .

1611618247 51 Git Reset Explained Cum se salveaza ziua cu comanda

Apoi, când folosim git commit, creăm un comitepe baza stării index . Deci noul comite (commit 3 în exemplul de mai jos) va include fișierul adăugat la index în prealabil.

1611618247 766 Git Reset Explained Cum se salveaza ziua cu comanda

Cu alte cuvinte, dir. de lucru are exact aceeași stare ca indexsi repertoriu .

Comanda git commit face și ramura actuală master indică nou-creatul comiteobiect.

1611618247 409 Git Reset Explained Cum se salveaza ziua cu comanda

Funcționarea interioară a resetării git

Îmi place să mă gândesc la git reset ca o comandă care inversează procesul descris mai sus (introducând o modificare în dir. de lucru, adăugându-l la index, și apoi comiteaducându-l la repertoriu ).

Resetarea Git are trei moduri de operare –--soft, --mixed, sau --hard. Le văd ca pe trei etape:

  • Etapa 1 – actualizare HEADgit reset --soft
  • Etapa 2 – actualizare indexgit reset --mixed
  • Etapa 3 – actualizare dir. de lucru git reset --hard

Etapa 1 – actualizare HEAD (git reset --soft)

Primul, git reset actualizează orice HEAD arata spre. Pentru git reset --hard HEAD~1 va muta ce HEAD indică (în exemplul de mai sus, master) la HEAD~1. Dacă— -softse folosește steagul, git reset se oprește acolo.

Continuând cu exemplul nostru de mai sus, HEAD va indica spre commit 2, și, astfel new_file.txt nu va face parte din arborele comiterii curente. Cu toate acestea, va face parte din index si dir. de lucru.

1611618248 535 Git Reset Explained Cum se salveaza ziua cu comanda

Uitandu-ma la git status, putem vedea că fișierul este într-adevăr pus în scenă, dar nu este comis:

1611618248 59 Git Reset Explained Cum se salveaza ziua cu comanda

Cu alte cuvinte, am revenit la etapa în care am folosit git add, dar nu am folosit încă git commit.

Etapa 2 – actualizați indexul la HEAD (git reset --mixed)

Dacă folosim git reset --mixed HEAD~1, atunci git nu se va opri după actualizarea oricărui lucru HEADarata spre ( master )la HEAD~1. De asemenea, va actualiza fișierul index către (deja actualizat) HEAD .

În exemplul nostru, asta înseamnă că index va avea aceeași stare ca comite 2 :

1611618248 315 Git Reset Explained Cum se salveaza ziua cu comanda

Așa că am readus procesul la etapă înainte de a utilizagit add– fișierul nou creat face acum parte din directorul de lucru, dar fișierul index si repertoriunu sunt.

1611618248 940 Git Reset Explained Cum se salveaza ziua cu comanda

Etapa 3 – actualizați direcția de lucru pentru indexare (git reset --hard)

Prin utilizarea git reset — hard HEAD~1, după actualizarea oricărui lucru HEADarata spre (master )la HEAD~1, precum și actualizarea fișierului index către (deja actualizat) HEAD , git va trece mai departe și va actualiza fișierul dir. de lucru să arate ca index.

În exemplul nostru, asta înseamnă că dir. de lucru va avea aceeași stare ca index,care are deja aceeași stare ca comite 2:

1611618248 985 Git Reset Explained Cum se salveaza ziua cu comanda

De fapt, am revenit la întregul proces chiar înainte de a crea my_file.txt.

Aplicarea cunoștințelor noastre la scenarii din lumea reală

Acum că înțelegem cum git reset funcționează, să aplicăm aceste cunoștințe pentru a ne salva ziua! ?

1. OOPS! Am comis ceva din greșeală.

Să luăm în considerare următorul scenariu. Am creat un fișier cu șirul This is very importnt, a pus-o în scenă și a comis-o.

1611618248 612 Git Reset Explained Cum se salveaza ziua cu comanda

Și apoi … Hopa! Ne-am dat seama că am avut o eroare de tastare. ?

Ei bine, acum știm că putem rezolva cu ușurință asta. Putem reveni la ultimul nostru commit și să recuperăm fișierul în direcția de lucru folosind git reset --mixed HEAD~1. Acum, putem edita conținutul fișierului nostru, îl putem pune în scenă și îl putem comite din nou.

Bacsis:în acest caz specific, am putea folosi și git commit --amend, așa cum este descris aici.

2. OOPS! Am angajat ceva către ramura greșită – și am nevoie de ea pe o ramură nouă

Am fost cu toții acolo. Am făcut niște lucrări și apoi le-am comis …

1611618248 604 Git Reset Explained Cum se salveaza ziua cu comanda

Nu, ne-am angajat master filială, deși ar fi trebuit să creăm o filială nouă și apoi să emitem o cerere de extragere. ?

În acest stadiu, mi se pare util să vizualizez starea în care ne aflăm și unde ne-ar plăcea să ajungem:

1611618248 406 Git Reset Explained Cum se salveaza ziua cu comanda

De fapt, există trei modificări între starea curentă și cea dorită.

Primul, new ramură indică angajamentul nostru recent adăugat. Al doilea, master indică comiterea anterioară. Al treilea, HEAD arata spre new.

Putem ajunge la starea dorită prin trei pași simpli:

Mai întâi, faceți new punctul de ramificare la commitul adăugat recent – acest lucru poate fi realizat pur și simplu prin utilizarea git branch new. Prin urmare, ajungem la următoarea stare:

1611618248 425 Git Reset Explained Cum se salveaza ziua cu comanda

În al doilea rând, faceți master indicați comiterea anterioară (cu alte cuvinte, la HEAD~1). Putem face asta folosind git reset --hard HEAD~1. Prin urmare, am ajuns la următoarea stare:

1611618248 211 Git Reset Explained Cum se salveaza ziua cu comanda

În cele din urmă, am vrea să fim în ramură new, adică faceHEADarata spre new. Acest lucru se realizează cu ușurință prin performanță git checkout new.

În întregime:

  • git branch new
  • git reset --hard HEAD~1
  • git checkout new

3. OOPS! Am angajat ceva către ramura greșită – și am nevoie de ea pe o altă ramură deja existentă

În acest caz, am parcurs aceiași pași ca în scenariul anterior – am făcut ceva lucru, apoi l-am angajat …

1611618248 99 Git Reset Explained Cum se salveaza ziua cu comanda

Nu, ne-am angajat master ramură, deși ar fi trebuit să ne angajăm pentru o altă ramură care există deja. ?

Să revenim la planșa noastră de desen:

1611618248 642 Git Reset Explained Cum se salveaza ziua cu comanda

Din nou, putem vedea că există câteva diferențe aici.

În primul rând, avem nevoie de cel mai recent angajament existing ramură. De cand master indică în prezent, putem pur și simplu să întrebăm gita lua recenta comitere de la master filiala și aplicați-o la existing ramură așa:

  • git checkout existing– trecerea la existing ramură
  • git cherry-pick master– aplicarea ultimului commit pe master ramură la curent (existing) ramură

Acum am ajuns la următoarea stare:

1611618249 609 Git Reset Explained Cum se salveaza ziua cu comanda

Acum trebuie doar să facem master indică mai degrabă comiterea anterioară decât cea mai recentă. Pentru asta putem:

  • git checkout master– schimbați ramura activă în master din nou.
  • git reset --hard HEAD~1– acum ne-am întors la filiala inițială.

Și am ajuns la starea dorită:

1611618249 988 Git Reset Explained Cum se salveaza ziua cu comanda

rezumat

În această postare, am învățat cum git reset operează și i-a clarificat cele trei moduri de operare –--soft, --mixed, și --hard.

Ne-am aplicat apoi cunoștințele despre git reset pentru a rezolva unele probleme din viața reală cu git .

Înțelegând calea git funcționează, putem aborda cu încredere tot felul de scenarii și, de asemenea, putem aprecia frumusețea acestui instrument?

În postările viitoare, vom acoperi suplimentargitcomenzi și cum ne pot ajuta să rezolvăm tot felul de situații nedorite.

Omer Rosenbaum, ÎnotDirector tehnologic. Expert în formare cibernetică și fondator al Checkpoint Security Academy. Autor al Rețele de calculatoare (în ebraică). Vizitează-l pe My Canalul canalului YouTube.

Resurse aditionale