>
<>
<>
= 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
#include
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 ..." per aggiornare gli elementi di cui sarà eseguito il commit)
(usa "git restore ..." 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.<
>
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(+)
}}}
<>
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
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