<
> <> <> = 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