A îmbina sau a face merge — este operația de combinare a două ramuri în Git, care unește modificările dintr-o ramură în alta. În dezvoltarea modernă, merge-ul este metoda standard de integrare a unei ramuri feature în ramura principală a proiectului. Potrivit GitHub Octoverse 2024, zilnic se execută peste 15 milioane de merge-uri. Merge — mecanismul cheie al colaborării, care permite unirea muncii mai multor dezvoltatori într-un singur produs.
Principalele puncte
Merge-ul în Git — este operația de combinare a două sau mai multe istorii de dezvoltare într-una singură. Când un dezvoltator îmbină o ramură, Git găsește automat strămoșul comun (base commit) și creează un commit de îmbinare nou care include modificările din ambele ramuri. Three-way merge — algoritmul standard care compară trei stări: strămoșul comun, prima ramură și a doua ramură.
Procesul de merge începe cu comanda git merge. Git determină punctul de divergență al ramurilor și aplică secvențial modificările din ramura sursă peste ramura țintă. Dacă modificările nu intră în conflict, Git execută fast-forward sau creează un merge commit în funcție de setări. Fast-forward — scenariul în care ramura țintă este pur și simplu mutată pe commit-urile ramurii sursă.
# Comută pe ramura țintă și îmbină
git checkout main
git merge feature/payment-module
# Îmbină cu no-fast-forward explicit
git merge --no-ff feature/payment-module
# Anulează îmbinarea dacă conflictele sunt prea complexe
git merge --abort
Flag-ul --no-ff (no fast-forward) forțează crearea unui merge commit chiar și atunci când fast-forward este posibil. Aceasta păstrează informația că modificările au fost făcute într-o ramură separată. Multe echipe preferă această abordare pentru a păstra ramificarea istoriei în formă explicită.
În Git există trei strategii principale de îmbinare a ramurilor, fiecare potrivită pentru un scenariu specific. Alegerea strategiei depinde de cultura echipei și de cerințele privind curățenia istoriei proiectului.
| Strategie | Rezultat | Când se aplică |
|---|---|---|
| Standard merge | merge commit + istorie completă | echipe care prețuiesc istoria completă |
| Squash merge | un commit, istorie comprimată | ramuri feature cu multe commit-uri mici |
| Rebase merge | istorie liniară, fără merge commit | ramuri feature personale, înainte de PR |
Standard merge creează un merge commit cu doi părinți. Istoria completă este păstrată, dar graful de ramificare devine mai complex. Squash merge combină toate commit-urile ramurii feature într-unul singur și îl aplică peste ramura țintă — istoria devine liniară și curată, dar se pierde informația despre etapele intermediare.
Rebase, deși nu este un merge propriu-zis, atinge același rezultat — modificările dintr-o ramură sunt transferate peste alta. Diferența constă în rescrierea istoriei: commit-urile ramurii feature sunt recreate deasupra ultimului commit al ramurii țintă. Aceasta oferă o istorie perfect liniară, dar necesită force push la trimitere.
Conflictul la merge apare când în două ramuri sunt modificate aceleași linii ale unui fișier. Git nu poate determina automat ce variantă să păstreze și necesită intervenția dezvoltatorului. Conflictele sunt afișate în fișiere sub formă de markeri speciali: <<<<<<<, =======, >>>>>>>.
Procesul de rezolvare a conflictului include mai mulți pași. Mai întâi, dezvoltatorul deschide fișierul cu conflict și selectează manual modificările necesare. Este important să nu alegi doar una dintre versiuni, ci să înțelegi logica ambelor modificări și să iei o decizie corectă. După editarea fișierului, markerii de conflict sunt eliminați, iar modificările sunt adăugate în staging area prin git add.
# Vezi lista fișierelor cu conflicte
git status
# Pornește mergetool (de ex., VS Code, IntelliJ)
git mergetool
# După rezolvarea tuturor conflictelor
git add .
git merge --continue
# Sau anulează îmbinarea complet
git merge --abort
Utilizarea instrumentelor vizuale de merge accelerează semnificativ rezolvarea conflictelor. VS Code, IntelliJ IDEA și GitKraken oferă interfețe cu trei panouri: ramura curentă, ramura de intrare și rezultatul. Instrumentul git mergetool deschide automat editorul configurat pentru fiecare fișier cu conflict.
Cea mai bună modalitate de a evita conflictele complexe este sincronizarea regulată a ramurii feature cu ramura principală. Dacă dezvoltatorul îmbină main în ramura sa o dată pe zi, conflictele vor fi mici și ușor de rezolvat. Acumularea modificărilor timp de o săptămână garantează conflicte complexe cu risc ridicat de erori.
Rebase și merge — două moduri de a combina modificări, iar alegerea între ele provoacă adesea dezbateri în echipe. Rebase mută commit-urile dintr-o ramură peste alta, rescriind istoria. Merge creează un nou commit de îmbinare, păstrând istoria ramificării. Fiecare abordare are avantajele și limitările sale.
Rebase este potrivit când un dezvoltator lucrează în propria ramură feature locală și dorește o istorie liniară curată înainte de a crea un Pull Request. După rebase, toate commit-urile se aliniază secvențial, fără merge commit-uri inutile. Totuși, rebase necesită force push și nu se aplică ramurilor pe care lucrează mai multe persoane simultan.
Regula de aur a Git: nu folosi rebase pe commit-uri care au fost deja trimise în depozitul comun. Aceasta garantează că istoria în ramura comună rămâne neschimbată, iar alți dezvoltatori nu vor întâlni commit-uri duplicate sau pierdute. Pentru integrarea ramurii feature în ramura principală, folosește merge prin Pull Request.
Procesul corect de merge — baza dezvoltării stabile. În munca de echipă modernă, merge-ul se execută nu prin consolă, ci prin Pull Request pe GitHub sau Merge Request în GitLab. PR trece prin code review, verificări automate CI și abia apoi este îmbinat în ramura principală.
Prima practică — îmbină doar după trecerea tuturor verificărilor. CI pipeline trebuie să construiască proiectul, să ruleze testele și să verifice calitatea codului. Dacă măcar o verificare nu a trecut, merge-ul este blocat. Platformele moderne (GitHub, GitLab) au protecție încorporată: branch protection rules blochează automat merge-ul la căderea CI.
A doua practică — nu îmbina niciodată cod stricat. Înainte de merge, dezvoltatorul trebuie să se asigure că modificările sale nu strică build-ul și nu regresează funcționalitatea existentă. Pentru aceasta există teste automate și code review.
A treia practică — curăță ramurile feature după merge. Ramura care a fost deja îmbinată trebuie ștearsă. Aceasta previne confuzia și aglomerarea depozitului. GitHub propune automat ștergerea ramurii după merge-ul PR, iar setările depozitului pot fi configurate pentru ștergere automată.
Întrebări frecvente
Merge-ul — îmbinarea a două ramuri Git într-una singură. Modificările dintr-o ramură sunt transferate în cealaltă printr-o îmbinare pe trei căi (three-way merge). Rezultatul este fixat într-un commit de îmbinare nou, care are doi părinți. Merge commit păstrează informația despre ce ramuri au fost îmbinate.
Merge creează un commit nou de îmbinare, păstrând istoria ramificării. Rebase rescrie istoria, mutând commit-urile peste altă ramură fără a crea un merge commit. Rebase oferă o istorie liniară, dar necesită force push. Merge este mai sigur pentru ramurile comune, rebase mai bun pentru cele personale.
Deschide fișierul cu conflict, găsește markerii <<<<<<<, ======= și >>>>>>>, selectează modificările dorite și elimină markerii. Adaugă fișierul prin git add și finalizează merge-ul cu git merge --continue. Folosește git mergetool pentru rezolvare vizuală în VS Code sau IntelliJ IDEA.
Pull Request (sau Merge Request) este obligatoriu la îmbinarea ramurii feature în ramura principală a proiectului. PR trece prin code review-ul colegilor și verificări automate CI. Acesta este standardul dezvoltării moderne. Push-ul direct în ramura main este interzis în majoritatea proiectelor.
Squash merge combină toate commit-urile ramurii feature într-unul singur înainte de îmbinare. Aceasta oferă o istorie curată a ramurii principale, fără commit-uri intermediare de lucru. Folosește squash merge când ramura feature conține multe commit-uri de serviciu (wip, fixes) și nu este nevoie să păstrezi toți pașii intermediari în istorie.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și