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

Merge și conflicte

Lectură estimată: 4 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.

Ai lucrat pe un branch, ai terminat. Acum trebuie să aduci munca înapoi în main. Operațiunea se numește merge, iar frica de ea vine dintr-un singur cuvânt: conflict.

Vestea bună: un conflict nu este o eroare și nu ai stricat nimic. Este doar Git care spune, corect: „aici doi oameni au schimbat aceeași linie, nu am de unde să știu care versiune e bună — decide tu".

Merge simplu

git switch main
git pull
git merge feature/pagina-contact

Dacă în main nu s-a întâmplat nimic între timp, Git face un fast-forward: mută pur și simplu indicatorul main înainte, pentru că nu e nimic de combinat.

Înainte:  A---B---C (main)
                   \
                    D---E (feature)

După:     A---B---C---D---E (main, feature)

Dacă între timp au apărut commit-uri și pe main, Git creează un merge commit, un commit cu doi părinți:

A---B---C---F---M (main)
         \     /
          D---E (feature)

Anatomia unui conflict

Conflictul apare doar când aceeași porțiune din același fișier a fost modificată în ambele părți. Dacă tu ai lucrat în header.php și colegul în footer.php, Git combină fără să te întrebe nimic.

Când apare, Git îți spune clar:

Auto-merging resources/views/contact.blade.php
CONFLICT (content): Merge conflict in resources/views/contact.blade.php
Automatic merge failed; fix conflicts and then commit the result.

Deschizi fișierul și găsești marcajele:

<<<<<<< HEAD
<h1>Contact</h1>
<p>Scrie-ne la contact@exemplu.ro</p>
=======
<h1>Ia legătura cu noi</h1>
<p>Telefon: 0700 000 000</p>
>>>>>>> feature/pagina-contact
  • între <<<<<<< HEAD și ======= e versiunea din branch-ul în care faci merge (de regulă main);
  • între ======= și >>>>>>> e versiunea care vine.

Cum rezolvi

Rezolvarea înseamnă să editezi fișierul până arată cum trebuie și să ștergi complet marcajele. Rezultatul poate fi una dintre versiuni, sau o combinație:

<h1>Ia legătura cu noi</h1>
<p>Scrie-ne la contact@exemplu.ro</p>
<p>Telefon: 0700 000 000</p>

Apoi marchezi fișierul ca rezolvat și finalizezi:

git add resources/views/contact.blade.php
git status          # vezi dacă mai sunt fișiere în conflict
git commit          # mesajul de merge e precompletat

Dacă te-ai încurcat și vrei să o iei de la capăt:

git merge --abort

Comanda te întoarce exact în starea de dinaintea merge-ului. E plasa ta de siguranță; folosește-o fără ezitare.

Greșeala numărul unu

Cea mai frecventă greșeală la conflicte este să uiți marcajele în fișier. Codul ajunge în producție cu <<<<<<< HEAD în el și pagina se rupe.

Verificare rapidă înainte de commit:

git diff --check
grep -rn "<<<<<<<" .

Unelte care te ajută

Nu trebuie să rezolvi conflictele în text brut. VS Code afișează butoane „Accept Current / Accept Incoming / Accept Both" direct în fișier. Există și:

git mergetool           # deschide unealta configurată
git checkout --ours  fisier.txt    # păstrează versiunea din branch-ul curent
git checkout --theirs fisier.txt   # păstrează versiunea care vine

Atenție la --ours / --theirs: aruncă complet cealaltă variantă. Sunt utile pentru fișiere generate (de exemplu un build), nu pentru cod scris de oameni.

Cum eviți conflictele mari

Conflictele nu se rezolvă cu comenzi mai deștepte, ci cu obiceiuri mai bune:

  • Branch-uri scurte. Un branch care trăiește trei săptămâni garantează durere. Unul de două zile, aproape niciodată.
  • Sincronizează des. Adu main în branch-ul tău periodic, nu doar la final.
  • Împarte munca pe fișiere diferite, când e posibil.
  • Nu reformata fișiere întregi în commit-uri care conțin și logică. Un „prettier pe tot proiectul" transformă orice merge într-un coșmar.
# în branch-ul tău, periodic:
git fetch origin
git merge origin/main

Conflicte în fișiere care nu sunt cod

Există două categorii de fișiere care produc conflicte urâte și pe care merită să le tratezi separat.

Fișierele de dependențe (package-lock.json, composer.lock) nu se rezolvă editând manual. Iei versiunea de pe main și regenerezi:

git checkout --theirs package-lock.json
npm install
git add package-lock.json

Migrările de bază de date nu produc conflict de text, dar produc conflict de realitate: doi colegi creează migrări cu aceeași tabelă sau modifică aceeași coloană. Git le va combina fără să se plângă, iar problema apare abia la rulare. Verifică întotdeauna ce migrări noi vin odată cu merge-ul:

git diff main --stat -- database/migrations

Ce faci când merge-ul aduce ceva stricat

Se întâmplă: ai făcut merge, ai împins, iar pe main ceva nu mai merge. Dacă merge-ul e deja public, nu rescrii istoricul, ci îl anulezi ca pe orice commit — cu o mențiune importantă, pentru că un merge commit are doi părinți și Git trebuie să știe la care dintre ei să se întoarcă:

git revert -m 1 <hash-ul-merge-commit-ului>

-m 1 înseamnă „păstrează linia principală", adică branch-ul în care ai integrat (de obicei main). Reține că, după un astfel de revert, dacă vrei să reintegrezi mai târziu același branch, va trebui să anulezi întâi revert-ul — altfel Git consideră că modificările au fost deja aduse.

Exercițiu (provoacă un conflict intenționat)

  1. Pe main, modifică prima linie din README și commite.
  2. Creează feature/titlu pornind de la commit-ul anterior, modifică aceeași linie diferit și commite.
  3. Fă merge în main și rezolvă conflictul păstrând o combinație a celor două variante.
  4. Repetă, dar de data asta folosește git merge --abort ca să te întorci.

Aplicație practică

Sarcina

Produce un conflict controlat în același rând din README.

Rezolvare orientativă și verificare

Citește ambele variante, rezolvă sensul, elimină marker-ele și rulează verificarea proiectului.

Greșeală de evitat

Acceptarea automată a unei părți poate pierde modificări necesare.

Documentație și surse

Verifică-ți înțelegerea

4 î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.