Acesta este cuvântul pe care fiecare dezvoltator îl urăște să îl vadă: conflict. 😱 Nu există nici o cale de a evita conflictul de îmbinare ocazional atunci când lucrați cu Git (sau alte sisteme de control al versiunilor).

Dar când vorbesc cu dezvoltatorii, aud deseori că există un sentiment de anxietate sau disconfort în jurul subiectului conflictelor de fuziune.

Gestionarea conflictelor rămâne adesea un loc întunecat și misterios: o situație în care lucrurile sunt rupte grav și nu este clar cum să ieși din el (fără a înrăutăți lucrurile).

Deși este adevărat că conflictele de îmbinare sunt o parte inevitabilă a vieții unui dezvoltator, disconfortul în aceste situații este complet opțional.

Intenția mea cu acest articol este de a aduce o anumită claritate acestui subiect: cum și când apar de obicei conflictele, ce sunt de fapt și cum să le rezolvi – sau să le anulezi.

Când înțelegeți corect aceste lucruri, veți putea face față conflictelor de îmbinare într-un mod mult mai relaxat și mai încrezător. 😍

Cum și când apar conflictele

Numele o spune deja: „conflictele de îmbinare” pot apărea în procesul de integrare a comitetelor dintr-o altă sursă.

Rețineți, totuși, că „integrarea” nu se limitează doar la „fuzionarea ramurilor”. Se poate întâmpla și atunci când refaceți sau refaceți interactiv, când efectuați o cireșă sau o tragere sau chiar când reaplicați un Stash.

Toate aceste acțiuni realizează un fel de integrare – și atunci pot apărea conflicte de îmbinare.

Cum sa intelegeti si sa rezolvati conflictele in Git

Dar, desigur, aceste acțiuni nu duc la un conflict de fuziune de fiecare dată (slava Domnului!). În mod ideal, ar trebui să vă regăsiți în aceste situații doar rareori. Dar când apar exact conflictele?

De fapt, capacitățile de fuzionare ale Git sunt unul dintre cele mai mari avantaje ale sale: fuzionarea sucursalelor funcționează fără efort de cele mai multe ori, deoarece Git este de obicei capabil să descopere lucrurile de unul singur.

Dar există situații în care schimbări contradictorii au fost făcute – și unde tehnologia pur și simplu nu poti decide ce este bine sau nu. Aceste situații necesită pur și simplu o decizie a unei ființe umane.

Adevăratul clasic este atunci când exact aceeași linie de cod a fost schimbat în două comitere, pe două ramuri diferite. Git nu are de unde să știe ce schimbare preferați! 🤔

Există și alte situații similare – de exemplu când a fost un fișier modificat într-o ramură și șters în altul – dar sunt puțin mai puțin frecvente.

GUI pentru desktop Git „Tower”, de exemplu, are un mod frumos de a vizualiza aceste tipuri de situații:

1612005246 22 Cum sa intelegeti si sa rezolvati conflictele in Git

Cum să știți când a avut loc un conflict

Nu vă faceți griji: Git vă va spune foarte clar când s-a întâmplat un conflict. 😉

În primul rând, vă va anunța imediat în situație, de exemplu, atunci când o fuziune sau rebase eșuează din cauza unui conflict:

$ git merge develop
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
CONFLICT (modify/delete): error.html deleted in HEAD and modified in develop. Version develop of error.html left in tree.
Automatic merge failed; fix conflicts and then commit the result.

După cum puteți vedea din exemplul de mai sus, când am încercat să realizez o îmbinare, am creat un conflict de îmbinare – iar Git comunică problema foarte clar și prompt:

  • A apărut un conflict în fișierul „index.html”.
  • A apărut un alt conflict în fișierul „error.html”.
  • Și, în cele din urmă, din cauza conflictelor, operațiunea de fuzionare a eșuat.

Acestea sunt situațiile în care trebuie să căutăm în cod și să vedem ce trebuie făcut.

În cazul puțin probabil în care ați trecut cu vederea aceste mesaje de avertizare atunci când s-a produs conflictul, Git vă informează în plus ori de câte ori executați git status:

$ git status
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add/rm <file>..." as appropriate to mark resolution)
	deleted by us:   error.html
	both modified:   index.html

Cu alte cuvinte: nu vă faceți griji neobservând fuzionează conflicte. Git se asigură că nu le puteți trece cu vederea.

Cum se anulează un conflict în Git și se reia

Conflictele de îmbinare vin cu un anumit aer de urgență. Și pe bună dreptate: va trebui să vă ocupați de ei înainte de a vă putea continua munca.

Dar, deși ignorarea lor nu este o opțiune, „gestionarea conflictelor de îmbinare” nu înseamnă neapărat că trebuie să le rezolvați. Se anulează ele sunt, de asemenea, posibile!

Acest lucru ar putea merita repetat: aveți întotdeauna opțiunea de a anula un conflict de fuziune și de a reveni la starea anterioară. Acest lucru este adevărat chiar și atunci când ați început deja să rezolvați fișierele aflate în conflict și vă aflați într-un impas.

În aceste situații, este minunat să rețineți că puteți oricând să o luați de la capăt și să vă întoarceți la o stare curată înainte ca conflictul să se întâmple.

În acest scop, majoritatea comenzilor vin cu un --abort opțiune, de exemplu git merge --abort și git rebase --abort:

$ git merge --abort
$ git status
On branch main
nothing to commit, working tree clean

Acest lucru ar trebui să vă ofere încrederea că chiar nu te poți încurca. Puteți oricând să avortați, să reveniți la o stare curată și să o luați de la capăt.

Cum arată într-adevăr conflictele în Git

Acum, în siguranță, știind că nimic nu se poate rupe, să vedem ce conflict chiar arată ca. sub capotă. Acest lucru îi va demitiza pe acei micuți bătăuși și, în același timp, te va ajuta să-ți pierzi respectul și să câștigi încredere în tine.

De exemplu, să analizăm conținutul fișierului „index.html” (aflat în prezent în conflict) într-un editor:

1612005246 676 Cum sa intelegeti si sa rezolvati conflictele in Git

Git a avut amabilitatea de a marca zona cu probleme în fișier, înglobând-o în <<<<<<< HEAD și >>>>>>> [other/branch/name]. Conținutul care vine după primul marker provine din ramura noastră de lucru actuală. În cele din urmă, o linie cu ======= caractere separă cele două schimbări conflictuale.

Cum se rezolvă un conflict în Git

Treaba noastră ca dezvoltatori acum este să curățăm aceste linii: după ce am terminat, fișierul trebuie să arate exact așa cum vrem să arate.

Ar putea fi necesar să discutați cu colegul de echipă care a scris „celelalte” modificări și să decideți ce cod este de fapt corect. Poate că este al nostru, poate că este al lor – sau poate un amestec între cele două.

Acest proces – curățarea fișierului și asigurarea faptului că conține ceea ce dorim de fapt – nu trebuie să implice nici o magie. Puteți face acest lucru pur și simplu deschizând editorul de text sau IDE și începând să efectuați modificările.

Cu toate acestea, de multe ori veți descoperi că acesta nu este cel mai eficient mod. Atunci instrumentele dedicate pot economisi timp și efort:

  • Instrumente Git GUI: Unele dintre interfețele grafice ale utilizatorului pentru Git pot fi de ajutor la rezolvarea conflictelor. GUI Tower Git, de exemplu, oferă un „Conflict Wizard” dedicat care ajută la vizualizarea și rezolvarea situației:
Cum sa intelegeti si sa rezolvati conflictele in Git
  • Instrumente dedicate de îmbinare: Pentru conflicte mai complicate, poate fi minunat să aveți la îndemână un „Instrument Diff & Merge”. Puteți configura instrumentul dorit folosind comanda „git config”. (Consultați documentația instrumentului pentru instrucțiuni detaliate.) Apoi, în caz de conflict, îl puteți invoca prin simpla tastare git mergetool. De exemplu, iată o captură de ecran a „Caleidoscop„pe macOS:
Cum sa intelegeti si sa rezolvati conflictele in Git

După curățarea fișierului – fie manual, fie într-un Git GUI sau Merge Tool – trebuie să comitem acest lucru ca orice altă modificare:

  • Prin utilizarea git add <filename> în fișierul (anterior) aflat în conflict, îl informăm pe Git că conflictul a fost rezolvat.
  • Când toate conflictele au fost rezolvate și adăugate în zona de etapă, trebuie să finalizați rezoluția prin crearea unui commit regulat.

Cum să devii mai sigur și mai productiv

Cu mulți ani în urmă, când am început să folosesc controlul versiunilor, conflictele de fuzionare m-au speriat în mod regulat: mi-a fost teamă că, în cele din urmă, am reușit să rup lucrurile definitiv. 😩

Abia când mi-am luat timp să înțeleg cu adevărat ce se întâmplă sub capotă am putut să fac față conflictelor cu încredere și eficiență.

Același lucru a fost adevărat, de exemplu, când am avut de-a face cu greșeli: o singură dată am învățat cum să anulezi greșelile cu Git am putut să devin mai încrezător și mai productiv în munca mea?

Vă recomand cu drag să aruncați o privire la gratuit “Trusa de prim ajutor pentru Git“, o colecție de scurte videoclipuri despre cum să anulați și să vă recuperați din greșelile cu Git.

1612005246 121 Cum sa intelegeti si sa rezolvati conflictele in Git

Distrează-te devenind un programator mai bun!

Despre autor

Tobias Günther este CEO al Turn, popularul client desktop Git care ajută peste 100.000 de dezvoltatori din întreaga lume să fie mai productivi cu Git.