13. Risolvere i conflitti di merge
13.1 Quando e perché si verifica un conflitto
Section titled “13.1 Quando e perché si verifica un conflitto”Un conflitto sorge quando si sta integrando una history in cui due versioni hanno modificato le stesse righe. Può accadere:
- all’avvio del merge: ci sono modifiche pendenti in working copy o staging; va “pulito” lo spazio di lavoro (con
stash,commit,checkoutoreset); - durante il merge: il conflitto è reale tra i commit del branch corrente (current) e quelli del branch in ingresso (incoming).
13.2 Un esempio pratico
Section titled “13.2 Un esempio pratico”mkdir git-merge-test && cd git-merge-test && git init .echo "initial content to edit later" > merge.txtgit add merge.txtgit commit -m "initial content"
# branch con una modifica alla stessa rigagit checkout -b merge-meecho "new content to merge later" > merge.txtgit commit -am "edited the content for conflict"
# nel frattempo, su main, un'altra modifica allo stesso puntogit checkout mainecho "content added to previous" >> merge.txtgit commit -am "appended content to merge.txt"
# mergegit merge merge-me# Auto-merging merge.txt# CONFLICT (content): Merge conflict in merge.txt# Automatic merge failed; fix conflicts and then commit the result.Il file in conflitto contiene i marker di Git:
<<<<<<< HEADinitial content to edit latercontent added to previous=======new content to merge later>>>>>>> merge-me- tra
<<<<<<<e=======: la versione del branch current (HEAD); - tra
=======e>>>>>>>: la versione del branch incoming.
git status elenca i file non risolti e suggerisce i comandi.
13.3 Tre modi di risolvere
Section titled “13.3 Tre modi di risolvere”- Accettare la versione corrente:
git checkout --ours merge.txt - Accettare la versione in arrivo:
git checkout --theirs merge.txt - Integrare a mano: si modifica il file fino a un contenuto corretto, poi:
git add merge.txt # dichiara il conflitto risoltogit commit # conclude il mergeAl termine, la history mostra il merge commit e i due genitori intatti:
$ git log --pretty=format:'%h %s (%an)' --date=short --graph* c9802c8 merged content due conflict (Me)|\| * 15416df edited the content for conflict (Me)* | 90640eb appended content to merge.txt (Frank)|/* 0a99708 initial content (Someone)Per annullare tutto: git merge --abort.
13.4 Capire meglio le due versioni
Section titled “13.4 Capire meglio le due versioni”Stile diff3 — aggiunge ai marker anche il contenuto del genitore comune:
git config merge.conflictstyle diff3<<<<<<< HEADinitial content to edit latercontent added to previous||||||| 0a99708initial content to edit later=======new content to merge later>>>>>>> merge-megit log --merge — mostra i commit in conflitto sui due branch, con -p anche i diff:
git log --merge -p merge.txtAnche gli editor offrono supporto visivo: VSCode, ad esempio, riconosce i marker di conflitto e propone azioni rapide (Accept Current / Accept Incoming / Accept Both), oltre a una vista a confronto.
⚠️ Attenzione alla terminologia: Git usa ours/theirs, le UI spesso current/incoming — che è più esplicita sul “verso” del merge. Nel merge di un feature branch su main, per Git ours sono anche i commit altrui già presenti su main, e theirs i propri commit del branch: non sempre “ours” significa “il mio lavoro”!
Dopo la risoluzione va verificato che il codice funzioni ancora; e se la situazione è ambigua, valutare di interrompere il merge e confrontarsi con i colleghi.