<<BR>>
<<Indice(depth=1)>>
<<Informazioni(forum="http://forum.ubuntu-it.org/viewtopic.php?f=46&t=590616"; rilasci="22.04")>>

= Introduzione =

'''Git''' è molto potente per quanto riguarda i '''branch''' (rami di sviluppo paralleli). Possono essere creare alberature del repository anche molto complesse in modo veloce da gestire.

Per poter seguire la seguente guida si presuppone:
 * di aver creato il progetto '''gitproject''' come [[Programmazione/Git#creare|indicato]];
 * di aver elaborato il progetto come mostrato nella [[Programmazione/Git/Commit|seguente pagina]].

= Creazione del branch secondario =

Verrà ora creato un ramo di sviluppo del progetto chiamato '''gp-1''' separato dal ramo principale '''master'''.

 0. Spostati all'interno della cartella del progetto:{{{
cd gitproject
}}}
 0. Per visualizzare i branch attivi digitare:{{{
git branch
}}}verrà restituito:{{{
* master
}}}che indica l'unico branch attivo.
 0. Per creare un nuovo branch col nome '''gp-1''' digitare:{{{
git branch gp-1
}}}
 0. Verificare nuovamente la lista dei branch:{{{
git branch
}}}che ora restituirà:{{{
  gp-1
* master
}}}L'asterisco identifica il '''branch attivo''', quello su cui stiamo lavorando in questo momento.
 0. Per lavorare sul branch '''gp-1''' occorre il comando '''checkout''', che ci permette di effettuare lo ''switch'' fra i branch:{{{
git checkout gp-1
}}}che stamperà un messaggio di conferma del passaggio:{{{
Si è passati al branch 'gp-1'
}}}
 0. Come ulteriore riprova è possibile verificare quale sia il branch attivo:{{{
git branch
}}}L'output:{{{
* gp-1
  master
}}}conferma che il branch gp-1 segnalato con l'asterisco è il branch attivo.
 * Il log:{{{
git lg
}}}L'output:{{{
* 5b235ad (HEAD -> gp-1, master) - Mario Rossi : Aggiunta data in stampa. (19 minuti fa)
* b7c1ae2 - Mario Rossi : Aggiunti sorgenti e Makefile (25 minuti fa)
* ba12845 - Mario Rossi : README aggiunto (51 minuti fa)
}}}mostra entrambi i branch. Dato che ancora sono identici puntano allo stesso commit.

= Modifiche al branch secondario =

 0. Apportare le modifiche al file `~/gitproject/src/main.cpp` digitando:{{{
sed -i '3 a \\tstd::cout << "Issue gp-1 implementata" << std::endl;' src/main.cpp
}}}
 0. Visualizzare il contenuto modificato del file digitando:{{{
cat src/main.cpp
}}}che risulterà:{{{
#include <iostream>
#include <iostream>
int main() {
	std::cout << "sab 17 feb 2024, 01:26:54, CET: Benvenuti su Git!" << std::endl;
	std::cout << "Issue gp-1 implementata" << std::endl;
	return 0;
}
}}}
 0. Controllare quindi lo stato:{{{
git status
}}}che risulta:{{{
Sul branch gp-1
Modifiche non nell'area di staging per il commit:
  (usa "git add <file>..." per aggiornare gli elementi di cui sarà eseguito il commit)
  (usa "git restore <file>..." per scartare le modifiche nella directory di lavoro)
	modificato:             src/main.cpp

nessuna modifica aggiunta al commit (usa "git add" e/o "git commit -a")
}}}Possiamo vedere che '''Git''' si è accorto della modifica, ma anche che stiamo modificando il nuovo branch (il messaggio mostra il nome del branch su cui stiamo lavorando).
 0. Eseguire il commit:{{{
git commit -a -m "Modificato codice per issue gp-1."
}}}L'output sarà:{{{
[gp-1 05b43f8] Modificato codice per issue gp-1.
 1 file changed, 1 insertion(+)
}}}
 0. Consultare il log:{{{
git lg
}}}che risulterà:{{{
* 05b43f8 (HEAD -> gp-1) - Mario Rossi : Modificato codice per issue gp-1. (53 secondi fa)
* 5b235ad (master) - Mario Rossi : Aggiunta data in stampa. (24 minuti fa)
* b7c1ae2 - Mario Rossi : Aggiunti sorgenti e Makefile (30 minuti fa)
* ba12845 - Mario Rossi : README aggiunto (56 minuti fa)
}}}Il branch master è rimasto inalterato (infatti è rimasto al commit precedente), mentre nel nuovo branch è stato memorizzato il commit appena creato.

== Verifica del programma nei branch ==

Ovviamente se proviamo a eseguire il programma otteniamo l'output modificato con la nostra aggiunta:

 0. Eseguire il programma nel branch '''gp-1''' digitando i comandi:{{{
make clean && make && bin/main
}}}l'ultimo comando restituirà:{{{
sab 17 feb 2024, 01:26:54, CET: Benvenuti su Git!
Issue gp-1 implementata
}}}
 0. Tornare nel branch '''master''':{{{
git checkout master
}}}
 0. Eseguire il programma nel branch '''master''' digitando i comandi:{{{
make clean && make && bin/main
}}}l'ultimo comando restituirà:{{{
sab 17 feb 2024, 01:26:54, CET: Benvenuti su Git!
}}}Come è possibile constatare si è ancora allo stato precedente, prima di eseguire il branch. A questo punto nel log si può vedere una cosa interessante:
 0. Consultare il log:{{{
git lg
}}}da cui risulta{{{
* 05b43f8 (gp-1) - Mario Rossi : Modificato codice per issue gp-1. (5 minuti fa)
* 5b235ad (HEAD -> master) - Mario Rossi : Aggiunta data in stampa. (27 minuti fa)
* b7c1ae2 - Mario Rossi : Aggiunti sorgenti e Makefile (34 minuti fa)
* ba12845 - Mario Rossi : README aggiunto (60 minuti fa)
}}}Da notare '''HEAD''' che adesso punta al commit '''master'''.

HEAD è quindi un puntatore al commit in cui attualmente ci troviamo. È possibile spostarsi in qualsiasi commit, non solo sugli ultimi dei rispettivi branch, digitando:{{{
git checkout SHA1
}}}dove SHA1 è il codice SHA1 del commit (i valori d8b610a, 1412239, ecc.. mostrati nel log).

= Modifica al branch principale =

Dall'ultimo log risulta di essere posizionati sul branch '''master''' e supponiamo di voler aggiungere una cartella di documentazione.

 0. Creare la directory `doc`:{{{
mkdir doc
}}}
 0. Creare il file `~/gitproject/doc/Changelog`:{{{
echo '== Changelog =='$'\n'$'\n''First release' > doc/Changelog
}}}
 0. Visualizzare il contenuto:{{{
cat doc/Changelog
}}}che risulterà:{{{
== Changelog ==

First release
}}}
 0. Aggiungere i file ed seguire il commit:{{{
git add doc/
git commit -a -m "Aggiunta cartella documentazione."
}}}che restituirà:{{{
[master 158633d] Aggiunta cartella documentazione.
 1 file changed, 3 insertions(+)
 create mode 100644 doc/Changelog
}}}
 0. Consultare il log:{{{
git lg
}}}che risulterà:{{{
* 158633d (HEAD -> master) - Mario Rossi : Aggiunta cartella documentazione. (32 secondi fa)
| * 05b43f8 (gp-1) - Mario Rossi : Modificato codice per issue gp-1. (8 minuti fa)
|/  
* 5b235ad - Mario Rossi : Aggiunta data in stampa. (31 minuti fa)
* b7c1ae2 - Mario Rossi : Aggiunti sorgenti e Makefile (37 minuti fa)
* ba12845 - Mario Rossi : README aggiunto (63 minuti fa)
}}}È possibile notare come adesso i due branch stiano prendendo '''strade parallele'''. Sono partiti da un punto in comune, ma ognuno sta avendo modifiche indipendenti.

= Merge =

Adesso siamo nella situazione in cui:

 * il branch '''master''' ha aggiunto la documentazione;
 * il branch '''gp-1''' ha implementato una ''feature''.

Verrà effettuato un '''merge''' ossia introdurre le modifiche fatte in un branch in un altro branch.<<BR>>
In particolare, vogliamo che nel branch '''master''' vengano introdotte le modifiche aggiunte nel branch '''gp-1'''. Vogliamo quindi effettuare il merge di '''gp-1''' su '''master'''.

Il comando per effettuare i merge in Git sarà del tipo:{{{
git merge ALTRO_MERGE
}}}

 0. Assicurarsi di essere nel branch '''master''':{{{
git branch
}}}cioé che risulti:{{{
  gp-1
* master
}}}
 0. Effettuare quindi il merge:{{{
git merge gp-1
}}}il cui output sarà:{{{
Merge made by the 'ort' strategy.
 src/main.cpp | 1 +
 1 file changed, 1 insertion(+)
}}}
<<Anchor(log_master)>>
 0. Consultare il log:{{{
git lg
}}}che restituisce:{{{
*   b92d7ff (HEAD -> master) - Mario Rossi : Merge branch 'gp-1' (3 minuti fa)
|\  
| * 05b43f8 (gp-1) - Mario Rossi : Modificato codice per issue gp-1. (14 minuti fa)
* | 158633d - Mario Rossi : Aggiunta cartella documentazione. (7 minuti fa)
|/  
* 5b235ad - Mario Rossi : Aggiunta data in stampa. (37 minuti fa)
* b7c1ae2 - Mario Rossi : Aggiunti sorgenti e Makefile (44 minuti fa)
* ba12845 - Mario Rossi : README aggiunto (70 minuti fa)
}}}Si può vedere che nel branch master è stato creato un nuovo commit, che è il commit di merge. Il suo commento dice che è stato effettuato il merge del branch '''gp-1'''. Questo significa che le modifiche che abbiamo apportato su questo branch sono state riportate sul branch corrente ('''master''').
 0. Per verificare che le modifiche apportate su '''gp-1''' siano state incluse nel '''master''', visualizzare il contenuto del file `~/gitproject/src/main.cpp`, digitare:{{{
cat src/main.cpp
}}}che restituisce:{{{
#include <iostream>
int main() {
	std::cout << "sab 17 feb 2024, 01:26:54, CET: Benvenuti su Git!" << std::endl;
	std::cout << "Issue gp-1 implementata" << std::endl;
	return 0;
}
}}}
 0. Digitare i comandi:{{{
make clean && make && bin/main
}}}L'ultimo comando restituirà:{{{
sab 17 feb 2024, 01:26:54, CET: Benvenuti su Git!
Issue gp-1 implementata
}}}

= Conclusioni =

 * È stato creato un branch secondario.
 * È stata applicata una ''issue'' al branch secondario.
 * Sono state riportate le modifiche sul branch principale.

E' importante notare che quello che e' stato appena fatto non è un mero esercizio. È il modo standard in cui si lavora in '''Git''' con progetti seri. Di solito i passi da effettuare sono i seguenti:

 0. Si decide la issue da aggiungere/rimuovere/modificare.
 0. Dal branch principale si crea un nuovo branch, con un nome identificativo della modifica (può essere il codice associato a Bugzilla, il nome '''gp-1''' ne è un esempio).
 0. Si lavora alla issue su branch secondario.
 0. Quando si completa, si effettua il merge sul branch principale in modo che il progetto includa le modifiche e siano rese pubblicamente disponibili.

Questo modo di lavorare permette di fare tutte le sperimentazioni del caso sul proprio branch, senza la preoccupazione di andare a intaccare il progetto sul ramo principale che ne rimarrà immune fino a quando la issue non è completamente testata e funzionante.

Se nel frattempo arriva un'altra issue più urgente (un bug da risolvere o quant'altro), viene semplicemente creato un altro branch da quello principale, come fatto in precedenza, e si lavora su quello. I branch sono indipendenti fra di loro e questo assicura grande flessibilità nella gestione del progetto.

= Ulteriori risorse =

 * [[Programmazione/Git|Guida a Git]]

----
CategoryProgrammazione