Ricerca nel sito web

Come usare l'unione di Git


Riepilogo: per unire un ramo di sviluppo nel ramo corrente, usa git merge dev-branch-name. Se ricevi avvisi di conflitto su un'unione, usa git merge --abort per ritirarti, oppure modifica i file interessati e poi salvali.

Git utilizza i rami per isolare i flussi di sviluppo, per evitare che il ramo di rilascio stabile venga inquinato. Portare il lavoro in un ramo nel flusso principale significa unire i rami. Ecco come lo fai.

Che cos'è un'unione in Git?

Git è stato progettato per rendere la ramificazione semplice e veloce. A differenza di altri sistemi di controllo della versione, il branching su Git è una questione banale. Soprattutto nei progetti multi-sviluppatore, il branching è uno degli strumenti organizzativi principali di Git.

Branche sandbox nuovi sforzi di sviluppo in modo che il codice possa essere modificato o aggiunto senza influire sul codice in altri rami, in particolare il ramo principale o master. Questo di solito contiene la versione stabile della tua base di codice.

Isolare queste modifiche dalla versione del codice stabile ha perfettamente senso. Ma prima o poi il nuovo codice verrà testato, rivisto e approvato per essere inserito nel ramo principale. A quel punto, devi unire il tuo ramo nel ramo principale.

In realtà, i rami possono avere rami secondari, quindi potresti unire il tuo ramo in un altro ramo anziché nel ramo principale. Ricorda solo che le unioni prendono sempre un ramo e lo uniscono in un ramo target , qualunque esso sia. Se vuoi unire il tuo ramo principale in un altro ramo, puoi farlo anche tu.

Come la maggior parte delle azioni in Git, esegui le unioni nel tuo repository locale e le invii al tuo repository remoto.

Preparazione per unire un ramo in Git

Abbiamo un piccolo progetto di sviluppo con un repository Git locale e un repository Git remoto. Abbiamo creato un ramo chiamato bugfix14 dal ramo master e abbiamo lavorato a una soluzione a un bug.

Quel lavoro è completato e abbiamo testato il nostro codice. Funziona tutto come previsto. Vogliamo implementare queste modifiche nel ramo principale in modo che la nostra correzione faccia parte della prossima versione del software.

C'è un po' di preparazione da fare prima di eseguire la fusione. Dobbiamo assicurarci che il ramo di destinazione, in questo caso il ramo master, e il ramo in cui ci uniremo siano entrambi aggiornati.

Per fare questo useremo il comando git status.

git status

  • Su ramo bugfix14: questo è il nostro ramo attuale.
  • Il tuo branch è aggiornato con 'origine/bugfix': il branch nel nostro repository locale ha la stessa cronologia di commit del branch nel repository remoto. Ciò significa che sono identici.
  • niente di cui eseguire il commit Non ci sono modifiche nell'area di staging che non siano state confermate.
  • albero di lavoro pulito: non ci sono modifiche non programmate nella directory di lavoro.

Tutti questi indicano che il ramo è aggiornato e siamo pronti a procedere. Se qualcuno di questi indicasse l'esistenza di modifiche, avremmo bisogno di metterle in scena, eseguirne il commit e inviarle al telecomando. Se qualcun altro ha lavorato su questi file, potremmo dover estrarre le modifiche dal repository remoto.

Il controllo del ramo in cui ci uniremo semplifica il processo di fusione. Ci permette anche di verificare che sia aggiornato. Diamo un'occhiata al ramo principale.

git checkout master
git status

Riceviamo le stesse conferme che il ramo master è aggiornato.

Esecuzione di un'unione

Prima di fonderci, i nostri commit hanno questo aspetto.

Il ramo bugfix14 è stato ramificato dal ramo master. C'è stato un commit nel ramo master dopo la creazione del ramo bugfix14. Ci sono stati un paio di commit nel ramo bugfix14.

Ci siamo assicurati che i nostri due rami siano aggiornati e abbiamo controllato il ramo master. Possiamo emettere il comando per unire il ramo bugfix14 nel ramo master.

git merge bugfix14

La fusione avviene. Il ramo bugfix14 esiste ancora, ma ora le modifiche apportate in quel ramo sono state unite nel ramo master.

In questo caso il comando merge esegue una unione a tre vie. Ci sono solo due rami, ma ci sono tre commit coinvolti. Sono il capo di entrambi i rami e un terzo commit che rappresenta l'operazione di unione stessa.

Per aggiornare il nostro repository remoto, possiamo utilizzare il comando git push.

git push

Alcune persone preferiscono eliminare i rami laterali dopo averli uniti. Altri si prendono cura di conservarli come documentazione della vera storia di sviluppo del progetto.

Se vuoi eliminare il ramo, puoi farlo usando il comando git branch con l'opzione -d (delete).

git branch -d bugfix14

Per eliminare il ramo nel repository remoto utilizzare questo comando:

git push origin --delete bugfix14

Avrai una cronologia di commit lineare, ma non sarà la vera storia.

Esecuzione di un'unione veloce in Git

Se non hai effettuato alcun impegno nel ramo master, la tua cronologia sarà simile a questa. Sembrerà anche questo se hai ribasato il tuo ramo di sviluppo in modo che sia collegato alla fine del ramo master.

Poiché non ci sono commit nel ramo master, per unire il ramo bugfix15, tutto ciò che Git deve fare è puntare il puntatore head master all'ultimo commit del ramo bugfix15.

Possiamo usare il solito comando git merge:

git merge bugfix15

Questo ci dà questo risultato.

Che è uguale a questo:

Che è proprio come questo:

Git eseguirà un'unione veloce ogni volta che può. Se i commit nel ramo master indicano che non è possibile un'unione con avanzamento rapido, Git utilizzerà una unione a tre vie.

Non puoi forzare un'unione con avanzamento rapido, dopotutto potrebbe non essere possibile, ma puoi dichiarare che sarà un'unione con avanzamento rapido o niente. C'è un'opzione che indica a Git di utilizzare un'unione veloce se possibile, ma di non eseguire un'unione a tre vie se non è possibile. L'opzione è --ff-only (solo unione veloce).

Questo unisce il ramo bugfix15 nel ramo master, ma solo se è possibile un'unione rapida.

git merge --ff-only bugfix15

Git si lamenterà e uscirà se non è possibile.

git merge --ff-only bugfix16

In questo caso, ci sono stati commit nel ramo master, quindi non è possibile un'unione rapida.

Come risolvere i conflitti di unione in Git

Se le stesse parti dello stesso file sono state modificate in entrambi i rami, i rami non possono essere uniti. È necessaria l'interazione umana per risolvere le modifiche in conflitto.

Qui, abbiamo apportato modifiche a un file chiamato rot.c in un ramo chiamato bugfix17 che vogliamo unire al ramo master. Ma “rot.c” è stato modificato anche nel ramo “master”.

git merge bugfix17

Quando proviamo a unirlo, riceviamo un avviso che ci sono conflitti. Git elenca i file in conflitto e ci dice che l'unione non è riuscita. Potremmo ritirarci completamente usando l'opzione --abort:

git merge --abort

Ma risolvere le fusioni non è così spaventoso come sembra. Git ha fatto del lavoro per aiutarci. Se modifichiamo uno dei file in conflitto, nel nostro caso ne abbiamo solo uno, troveremo le sezioni di codice in conflitto evidenziate per noi.

Ogni conflitto è delimitato da sette caratteri minori di “<<<<<<<” e sette caratteri maggiori di “>>>>>>>“, con sette segni di uguale “=======” tra loro.

  • Il codice sopra i segni di uguale proviene dal ramo in cui stai unendo in.
  • Il codice sotto il segno di uguale è il codice del ramo che stai tentando di unire.

Puoi facilmente cercare uno dei set di sette caratteri e passare da un conflitto all'altro attraverso il tuo file. Per ogni conflitto, devi scegliere quale serie di modifiche manterrai. Devi modificare il codice che stai rifiutando e le righe di sette caratteri che Git ha aggiunto.

Manterremo il codice dal ramo bugfix17. Dopo la modifica, il nostro file ha questo aspetto.

Ora possiamo procedere con l'unione. Ma nota, usiamo il comando commit per farlo, non il comando merge.

Effettuiamo il commit della modifica mettendo in scena il file ed eseguendo il commit come di consueto. Verificheremo lo stato prima di effettuare il commit finale.

git add rot.c
git status
git commit -m "Merged bugfix17"

L'unione è completa. Ora possiamo inviarlo al nostro repository remoto.

Tutto si fonde alla fine

Tutti i rami devono essere uniti, alla fine, in modo che i cambiamenti in essi non diventino orfani e dimenticati.

Unire i rami è facile, ma gestire i conflitti può diventare complicato in team impegnati e più grandi. La risoluzione dei conflitti può richiedere l'input di ogni sviluppatore solo per spiegare cosa fa il loro codice e perché hanno apportato le modifiche. Devi capirlo, prima di poter prendere una decisione informata su quali modifiche conservare.

Purtroppo, Git non può fare a meno di questo.