Merge — cos'è, tipi di fusione e meccanismo di funzionamento

Autore: IT Sectr Pubblicato: 2026-05-10 Tempo di lettura: 10 min

Merge è un'operazione in Git che combina le modifiche da un ramo all'altro, creando un commit di fusione (merge commit). Git supporta diverse strategie: fast-forward (storia lineare), three-way merge (con creazione di un merge commit) e squash merge (compressione di tutti i commit in uno). Secondo git-scm.com, 2025, il merge rimane il meccanismo di integrazione del codice più utilizzato nello sviluppo Git di squadra.

Punti chiave

  • Merge — operazione di fusione di rami in Git con o senza commit di fusione
  • Fast-forward merge — fusione lineare senza commit aggiuntivo quando non c'è divergenza
  • Three-way merge — crea un merge commit quando i rami divergono
  • Squash merge — comprime tutti i commit del ramo in uno prima della fusione
  • Conflitti sorgono quando le stesse righe vengono modificate in entrambi i rami

Cos'è Merge?

Merge (fusione) è un'operazione fondamentale in Git che combina le modifiche da un ramo (source) a un altro (target). Come risultato della fusione, il ramo target riceve tutti i commit dal ramo source che non erano ancora presenti in esso. A seconda della situazione, Git può eseguire il merge in tre modi diversi.

Il principale valore del merge è preservare la storia: il merge commit registra il fatto della fusione dei rami, conservando informazioni su quando e quali rami sono stati fusi. Ciò facilita l'audit delle modifiche, la ricerca di regressioni e la comprensione della cronologia dello sviluppo. Nei progetti grandi, il merge commit è il metodo standard di integrazione del codice.

Secondo GitLab Flow, i merge commit sono utilizzati nel 73% dei team che lavorano con Git. Gli approcci alternativi (rebase, squash) sono preferiti da team orientati a una storia lineare. La scelta della strategia dipende dalla dimensione del team, dalla frequenza dei rilasci e dalle convenzioni accettate nel progetto.

Quando si verifica Merge

Merge è necessario quando uno sviluppatore ha terminato di lavorare su una funzionalità e vuole integrarla in develop o main. Uno scenario tipico: uno sviluppatore ha creato un ramo feature da develop, ci ha lavorato per diversi giorni, e durante questo tempo sono apparsi nuovi commit di altri membri del team in develop. Prima della fusione, è necessario combinare le modifiche — e per questo si usa il merge.

Senza merge, è impossibile lavorare collaborativamente su un unico codice in Git. Ogni volta che due sviluppatori apportano modifiche simultanee a una stessa base di codice, i loro rami divergono. Il merge è l'unico modo per riunire queste modifiche senza perdita di dati.

Tipi di fusione in Git

Git supporta tre tipi di merge, ciascuno progettato per il proprio scenario. La scelta del tipo di fusione influisce sulla storia dei commit, sulla facilità di rollback e sulla leggibilità del log.

Fast-forward merge

Fast-forward si verifica quando il ramo target non ha avuto nuovi commit dalla creazione del ramo source. In questo caso, Git sposta semplicemente il puntatore del ramo target in avanti, all'ultimo commit del ramo source. La storia rimane lineare, senza merge commit.

bash
# Fast-forward merge: develop non è cambiato dalla creazione di feature
git checkout develop
git merge feature/new-login

# Risultato: il puntatore develop si è spostato alla fine di feature
# Nessun merge commit è stato creato

Fast-forward è conveniente per rami di breve durata dove uno sviluppatore ha lavorato da solo. Ma questo approccio ha uno svantaggio: si perde l'informazione che il ramo è esistito — tutti i commit sembrano fatti direttamente in develop.

Three-way merge

Three-way merge viene eseguito quando entrambi i rami hanno nuovi commit dopo il punto di divergenza. Git crea un merge commit separato con due genitori, che registra il fatto della fusione dei rami. Questo approccio è raccomandato per i rami feature nello sviluppo di squadra.

bash
# Three-way merge forzato con il flag --no-ff
git checkout develop
git merge --no-ff feature/new-login

# Un merge commit è stato creato con il messaggio predefinito
# Puoi impostare il tuo messaggio tramite -m
git merge --no-ff feature/new-login -m "Merge feature/new-login into develop"

Il flag --no-ff garantisce la creazione di un merge commit, anche se il fast-forward è possibile. Questa è una buona pratica per preservare le informazioni di ramificazione in un progetto.

Squash merge

Squash merge comprime tutti i commit del ramo source in uno e lo applica al target. La storia della funzionalità viene persa — un singolo commit con tutte le modifiche finisce nel ramo. Questo è conveniente quando i commit dettagliati in un ramo feature non aggiungono valore alla storia generale.

bash
# Squash merge: tutti i commit di feature sono compressi in uno
git checkout develop
git merge --squash feature/experimental
git commit -m "feat: experimental login flow (squashed)"

Squash è adatto per bozze, rami sperimentali e situazioni in cui è importante mantenere una storia pulita. Lo svantaggio è che la connessione con i commit originali viene persa, rendendo più difficile il rollback delle modifiche individuali.

Strategie Ours e Theirs

Ours e Theirs sono due strategie speciali di merge in Git. Ours ignora completamente le modifiche dal ramo source, mantenendo solo ciò che è nel target. Theirs, al contrario, accetta la versione del ramo source in qualsiasi conflitto. Queste strategie sono utili quando si fondono grandi quantità di codice quando si sa in anticipo quale versione deve prevalere.

Come funziona Merge

Il meccanismo di merge in Git si basa sul confronto di tre punti: l'antenato comune (merge base), lo stato del ramo source e lo stato del ramo target. Git trova il merge base — l'ultimo commit comune a entrambi i rami — e calcola quali modifiche sono avvenute in ciascun ramo dopo la divergenza.

  • Passo 1 — Git determina il merge base: l'ultimo commit presente in entrambi i rami
  • Passo 2 — Git costruisce due diff: dal merge base a source e dal merge base a target
  • Passo 3 — Git tenta di applicare entrambi i set di modifiche al merge base
  • Passo 4 — Se le modifiche non sono in conflitto — il merge si completa automaticamente
  • Passo 5 — Se c'è un conflitto — Git si ferma e richiede una risoluzione

Git utilizza un algoritmo di fusione a tre vie che considera non solo le due versioni del file confrontate, ma anche il loro antenato comune. Grazie a ciò, Git può risolvere automaticamente situazioni in cui le modifiche in un ramo non influenzano le aree modificate dell'altro — anche se entrambi i file sono stati modificati.

Esempio di funzionamento del merge

Consideriamo uno scenario: due sviluppatori lavorano su file diversi in uno stesso ramo feature. Il primo ha modificato LoginActivity.kt, il secondo ha modificato ProfileFragment.kt. Quando fondono le loro modifiche, Git vede che le modifiche hanno interessato file diversi ed esegue il merge automaticamente, senza intervento umano.

Se entrambi gli sviluppatori hanno modificato LoginActivity.kt, ma in metodi diversi — Git gestirà anche questo automaticamente, fondendo le modifiche riga per riga. Un conflitto sorge solo se entrambi hanno modificato le stesse righe o se uno ha cancellato codice che l'altro ha modificato.

Risoluzione dei conflitti in Merge

Un conflitto di merge si verifica quando Git non può fondere automaticamente le modifiche perché entrambi i rami hanno modificato le stesse righe in modo diverso. In questo caso, Git segna le aree in conflitto nei file e attende la risoluzione manuale dallo sviluppatore.

Le aree in conflitto vengono contrassegnate con marcatori speciali: <<<<<<< HEAD mostra il codice del ramo target, ======= è il separatore, >>>>>>> source-branch mostra il codice del ramo source. Lo sviluppatore deve scegliere manualmente quale versione mantenere o combinarle.

bash
# 1. Eseguire il merge e vedere il conflitto
git merge feature/new-login
# Output: CONFLICT (content): Merge conflict in LoginActivity.kt

# 2. Visualizzare l'elenco dei file con conflitti
git status
# both modified: src/ui/login/LoginActivity.kt

# 3. Risolvere il conflitto: modificare il file, rimuovere i marcatori
# 4. Aggiungere il file risolto e completare il merge
git add src/ui/login/LoginActivity.kt
git merge --continue
# o: git commit (senza --continue)

Esistono strumenti per risolvere i conflitti: git mergetool apre un merger visuale (Meld, Beyond Compare, VS Code). Molti sviluppatori preferiscono risolvere i conflitti nell'IDE — IntelliJ IDEA e Android Studio forniscono uno strumento integrato con confronto a tre pannelli che semplifica notevolmente questo processo.

Suggerimenti per risolvere i conflitti: comprendere sempre cosa fa ciascun lato del conflitto, non eliminare il codice altrui senza comprenderne la logica, e se il conflitto è troppo complesso — coinvolgere gli autori di entrambi i rami in una risoluzione congiunta.

Merge vs Rebase: quando scegliere cosa

La scelta tra Merge e Rebase è una delle decisioni architetturali più comuni in Git. Entrambi gli approcci combinano le modifiche, ma lo fanno in modo diverso: merge preserva la storia di ramificazione, rebase riscrive la storia rendendola lineare.

  • Merge — preserva il contesto: si può vedere quando e da quale ramo è stata fatta una fusione. Migliore per rami pubblici (develop, main) e lavoro di squadra
  • Rebase — crea una storia lineare pulita senza merge commit extra. Migliore per rami feature personali prima della revisione
  • Regola: non fare mai rebase di rami pubblici che altri sviluppatori stanno usando

Molti team utilizzano un approccio ibrido: rebase per aggiornare il ramo feature con develop (git rebase develop), e poi merge con il flag --no-ff per registrare la fusione. Questo dà una storia pulita all'interno della funzionalità e punti di fusione informativi a livello di develop.

Domande frequenti

Qual è la differenza tra merge e merge --no-ff?

Senza --no-ff Git esegue un fast-forward merge se possibile — sposta semplicemente il puntatore del ramo. Con --no-ff Git crea sempre un merge commit, preservando le informazioni di ramificazione. Raccomandato per i rami feature nello sviluppo di squadra.

Cosa fare se un conflitto di merge è molto grande?

Usa git mergetool o lo strumento integrato dell'IDE. Se il conflitto coinvolge decine di file — i rami potrebbero essersi discostati troppo. In questo caso, discuti il piano di fusione con il team, possibilmente suddividendolo in più fasi.

Si può annullare un merge?

: git merge --abort annulla il merge se non è ancora stato completato (conflitto). Se il merge è già stato completato — usa git reset --hard HEAD~1 o git revert -m 1 <merge-commit> per un rollback sicuro.

È necessario creare un merge commit per ogni funzionalità?

Raccomandato per il lavoro di squadra. Il merge commit registra il fatto della fusione, contiene riferimenti a entrambi i rami e semplifica la comprensione della storia. Per rami personali o sperimentali, squash merge o fast-forward sono accettabili.

Come funziona il merge con i file binari?

Git non può fondere automaticamente i file binari — seleziona una versione per intero. Per i file binari (immagini, .aab, .apk) si raccomanda di minimizzare le modifiche parallele e utilizzare Git LFS per file grandi.

Riepilogo

  • Merge — operazione Git di base per combinare modifiche da un ramo all'altro
  • Fast-forward — fusione lineare senza merge commit quando non c'è divergenza
  • Three-way merge — crea un merge commit con due genitori, preserva il contesto
  • Squash merge — comprime tutti i commit del ramo in uno, perdendo la storia della funzionalità
  • Conflitti sorgono quando le stesse righe vengono modificate e vengono risolti manualmente
  • Merge differisce da Rebase: il primo preserva la ramificazione, il secondo rende la storia lineare
  • Per rami pubblici si raccomanda merge con --no-ff, per personali — rebase o squash

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche