>
<>
<>
= Introduzione =
'''Git''' offre una gestione avanzata dei '''branch''' (rami di sviluppo paralleli), consentendo di creare e gestire strutture del repository anche molto complesse in modo rapido.
Per seguire questa guida è necessario:
* aver [[Programmazione/Git#Creazione_repository|creato il progetto]] '''gitproject''' come indicato nella pagina principale;
* aver [[Programmazione/Git/Commit|elaborato il progetto]] come mostrato nella pagina relativa ai commit.
{{{#!wiki important
Quello che è rappresentato in questa guida sottostante 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.
= Gestione dei branch =
{{{#!wiki important
Si ricorda che tutte le operazioni di gestione del repository (commit, visualizzazione cronologia, gestione branch, ecc.) devono essere eseguite posizionandosi all'interno della directory del progetto (ad esempio `~/gitproject`). In questo modo '''Git''' può accedere alla sottocartella nascosta `.git` necessaria per il corretto funzionamento dei comandi.
}}}
[[AmministrazioneSistema/ComandiBase#cd|Spostarsi]] all'interno della cartella del progetto, digitando nel [[AmministrazioneSistema/Terminale|terminale]] il seguente comando:{{{
cd gitproject
}}}
== Visualizzazione branch attivi ==
Per visualizzare i branch attivi:
0. Digitare nel [[AmministrazioneSistema/Terminale|terminale]] il comando:{{{
git branch
}}}verrà restituito:{{{
* master
}}}
{{{#!wiki note
L'asterisco identifica il '''branch attivo''', quello su cui si sta lavorando in questo momento.
}}}
== Creazione del branch secondario ==
Verrà ora creato un ramo di sviluppo del progetto chiamato '''gp-1''' separato dal ramo principale '''master'''.
0. Per creare un nuovo branch col nome '''gp-1''' digitare nel [[AmministrazioneSistema/Terminale|terminale]] il seguente comando:{{{
git branch gp-1
}}}
0. [[#Visualizzazione_branch_attivi|Verificare]] nuovamente la lista dei branch:{{{
git branch
}}}che restituirà:{{{
gp-1
* master
}}}L'asterisco identifica il '''branch attivo''', quello su cui stiamo lavorando in questo momento.
== Effettuare switch fra i branch ==
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. [[#Visualizzazione_branch_attivi|Verificare]] quale sia il branch attivo. L'output sarà:{{{
* gp-1
master
}}}conferma che il branch attivo è ora `gp-1`.
0. [[Programmazione/Git#Visualizzazione_della_cronologia|Ispezionare la cronologia]] per verificare la posizione dei rami `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 una modifica al file `src/main.cpp` presente nella directory del progetto tramite il seguente comando:{{{
sed -i '3 a \\tstd::cout << "Issue gp-1 implementata" << std::endl;' src/main.cpp
}}}
0. [[AmministrazioneSistema/ComandiBase#cat.2C_zcat_e_less|Visualizzare]] il contenuto modificato del file per verifica, digitando il comando:{{{
cat src/main.cpp
}}}che risulterà:{{{
#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 lo stato del repository per osservare la notifica della modifica:{{{
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 si sta modificando il nuovo branch (il messaggio mostra il nome del branch su cui si sta lavorando).
0. [[Programmazione/Git/Commit|Eseguire il commit]] per registrare il cambiamento nel branch corrente:{{{
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. [[Programmazione/Git#Visualizzazione_della_cronologia|Verificare lo stato]] dei commit tramite la cronologia grafica:{{{
git lg
}}}L'output mostrerà che il branch '''master''' è rimasto fermo al commit precedente, mentre '''gp-1''' risulterà avanzato con il nuovo commit. 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)
}}}
== 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'output includerà la stringa "Issue gp-1 implementata":{{{
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 nuovamente il programma:{{{
make clean && make && bin/main
}}}l'ultimo comando restituirà:{{{
sab 17 feb 2024, 01:26:54, CET: Benvenuti su Git!
}}}In questo caso, l'output sarà quello dello stato precedente, confermando che il ramo principale non è stato intaccato.
0. [[Programmazione/Git#Visualizzazione_della_cronologia|Ispezionare la cronologia]] per verificare la posizione dei rami `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 si trova. È 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 =
Mentre il branch '''gp-1''' è isolato, è possibile procedere con lo sviluppo parallelo sul '''master'''.
0. [[AmministrazioneSistema/ComandiBase#mkdir|Creare una directory]] di documentazione e un file Changelog, digitando nel [[AmministrazioneSistema/Terminale|terminale]] i seguenti comandi:{{{
mkdir doc
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. [[Programmazione/Git#Visualizzazione_della_cronologia|Ispezionare la cronologia]] per verificare la posizione dei rami `git lg`. 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''':
0. Assicurarsi di essere nel branch di destinazione ('''master''') tramite `git branch`.:{{{
git branch
}}}cioé che risulti:{{{
gp-1
* master
}}}
0. Effettuare 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(+)
}}}
{{{#!wiki note
Il comando per effettuare i merge in Git sarà del tipo `git merge MERGE`
}}}
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. [[Programmazione/Git#Visualizzazione_della_cronologia|Controllare lo storico]] con `git lg`: verrà visualizzato un nuovo commit di merge che riunisce i rami. Verificando il contenuto di `src/main.cpp`, la modifica di gp-1 risulterà ora integrata. Risulterà:{{{
* 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''').
{{{#!wiki note
Il flusso di lavoro standard prevede la creazione di un branch per ogni issue o funzionalità, lo sviluppo isolato e l'integrazione finale nel ramo principale solo a test completati. Questo garantisce la stabilità del progetto anche durante fasi di sperimentazione.
}}}
##<>
##== Consultare i log ==
## 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.
= Ulteriori risorse =
* [[Programmazione/Git|Guida a Git]]
----
CategoryProgrammazione