Kratak odgovor
Git merge konflikt nastaje kada dve grane izmene isti deo fajla. Rešava se tako što otvorite fajlove sa oznakama konflikta, ručno izaberete ili spojite izmene, sačuvate, pokrenete `git add` i završite sa `git commit` ili `git merge --continue`. Ako se zapetljate, `git merge --abort` vraća sve na stanje pre merge-a.
Kako se problem prepoznaje
- Poruka `CONFLICT (content): Merge conflict in ...` u terminalu
- Fajlovi sadrže oznake `<<<<<<<`, `=======`, `>>>>>>>`
- `git status` prikazuje fajlove pod "Unmerged paths"
- Merge je započet ali nije završen, `git log` ne pokazuje novi commit
- Editor ili IDE prikazuje crvene markere na linijama sa konfliktom
Najčešći uzroci
Izmene istog dela fajla u dve grane
Dve grane su menjale iste linije koda ili isti blok teksta, pa Git ne može automatski da odluči koja verzija je ispravna.
Brisanje ili premeštanje fajla u jednoj grani
Ako je fajl obrisan u jednoj grani, a izmenjen u drugoj, Git prijavljuje modify/delete konflikt.
Istovremeni rad na istoj grani
Dva developera su menjala isti fajl bez povlačenja najnovijih izmena, pa merge kasnije otkriva preklapanje.
Prilagođena merge podešavanja
`.gitattributes` ili prilagođeni merge drajveri mogu uticati na to kako Git tretira izmene i kada prijavljuje konflikt.
Rešenje korak po korak
- 1
Proverite stanje repozitorijuma
Pokrenite
git status. Fajlovi sa konfliktom biće navedeni pod "Unmerged paths". Zapišite ih ili otvorite terminal u korenu projekta. Ne prekidajte merge dok ne odlučite šta želite. - 2
Otvorite fajl sa konfliktom
Otvorite svaki fajl iz liste u editoru. Potražite oznake
<<<<<<< HEAD,=======i>>>>>>> ime-grane. Kod podrazumevanog stila, deo između<<<<<<<i=======je vaša trenutna grana, a deo između=======i>>>>>>>dolazi iz grane koja se spaja. Ako koristitediff3stil, postoji i deo sa zajedničkim pretkom između|||||||i=======. - 3
Ručno spojite izmene
Obrišite sve oznake konflikta i ostavite samo željeni kod. Možete zadržati jednu stranu, drugu, ili kombinovati obe. Vodite računa o zagradama, zarezima i uvlačenju. Ako niste sigurni, otvorite istoriju fajla (
git log -- fajl) da vidite šta je ko menjao. - 4
Koristite editor ili IDE za pregled
VS Code nudi opcije "Accept Current Change", "Accept Incoming Change" i "Accept Both Changes"; slične opcije imaju i drugi editori. To je brže, ali uvek pregledajte rezultat. Ne prihvatajte slepo obe strane ako se logika koda preklapa.
- 5
Sačuvajte i označite kao rešeno
Kada završite fajl, sačuvajte ga i pokrenite
git add ime-fajla. Ponovite za sve fajlove iz liste.git statussada treba da prikaže "All conflicts fixed but you are still merging". - 6
Završite merge
Pokrenite
git commit(bez-mako želite da uredite poruku) iligit merge --continue. Time se kreira merge commit. Proveritegit log --oneline -3da vidite da je merge zabeležen. - 7
Testirajte pre push-a
Pokrenite build i testove (
npm test,mvn testili šta god projekat koristi). Konflikt može sakriti grešku koja se vidi tek pri izvršavanju. Tek kada testovi prođu, uraditegit push. - 8
Ako želite da odustanete
Komanda
git merge --abortvraća radni direktorijum na stanje pre početka merge-a. Koristite je ako procenite da je bolje da prvo povučete izmene ili se konsultujete sa kolegom. Ne koristitegit reset --hardako imate nesačuvane izmene.
Kada konflikt postane prevelik
Ako fajl ima desetine konfliktnih blokova ili ne razumete kod, nemojte nasumično birati strane. Ako želite da sačuvate stanje pre merge-a, napravite rezervnu granu pre početka merge-a (git branch moja-rezerva); ona ne čuva nesačuvane izmene u radnom direktorijumu. Ako počinjete merge iznova, na ciljnoj grani možete koristiti git merge --no-commit da pregledate izmene pre commit-a. Za velike konflikte korisno je uključiti git config merge.conflictstyle diff3 koji prikazuje i zajedničkog pretka, što olakšava razumevanje. Ako konflikt uključuje binarne fajlove, Git ne može da ih spoji; tada morate ručno izabrati jednu verziju (git checkout --ours fajl ili --theirs), zatim pokrenuti git add fajl.
Kako da sprečite da se ponovi
- Često povlačite izmene sa glavne grane (`git pull --rebase`) pre nego što započnete veći posao.
- Držite izmene male i fokusirane na jedan zadatak; češće commit-ujte.
- Dogovorite se u timu ko menja koje fajlove i delove koda.
- Uključite `git config merge.conflictstyle diff3` da biste lakše razumeli konflikte.
Kada je bolje pozvati stručnjaka
Ako konflikt uključuje desetine fajlova, binarne fajlove ili ne razumete kod dovoljno da bezbedno spojite izmene, pozovite IT podršku ili iskusnijeg kolegu da zajedno rešite konflikt i sačuvate istoriju.
Razvoj softvera i proizvoda · Aplikacije po meri, SaaS i MVP za 4 do 8 nedeljaČesta pitanja
Šta znače oznake `<<<<<<<`, `=======` i `>>>>>>>`?
`<<<<<<< HEAD` označava početak vaše trenutne grane, `=======` razdvaja dve verzije, a `>>>>>>> ime-grane` označava kraj dela iz grane koja se spaja. Sve oznake konflikta moraju biti obrisane pre nego što označite fajl kao rešen.
Mogu li da poništim merge ako sam već pokrenuo `git add`?
Da, `git merge --abort` radi sve dok niste završili merge commit. Ako ste već napravili merge commit i niste ga push-ovali, možete ga poništiti sa `git reset --hard HEAD~1`, ali prvo napravite rezervnu granu ili kopiju repozitorijuma. Ako je commit već push-ovan, koristite `git revert -m 1 <hash>`.
Kako da rešim konflikt u binarnom fajlu?
Git ne može automatski da spoji binarne fajlove. Odlučite koja verzija je ispravna i pokrenite `git checkout --ours fajl` (vaša grana) ili `git checkout --theirs fajl` (druga grana), zatim `git add fajl`.