Wiki Ubuntu-it

Indice
Partecipa
FAQ
Wiki Blog
------------------
Ubuntu-it.org
Forum
Chiedi
Chat
Cerca
Planet
  • Pagina non alterabile
  • Informazioni
  • Allegati
  • Differenze per "Programmazione/Git/Branch"
Differenze tra le versioni 2 e 16 (in 14 versioni)
Versione 2 del 06/12/2014 00.45.07
Dimensione: 22643
Autore: jeremie2
Commento:
Versione 16 del 31/03/2026 09.54.18
Dimensione: 12810
Autore: ivantu
Commento: +correzioni;
Le cancellazioni sono segnalate in questo modo. Le aggiunte sono segnalate in questo modo.
Linea 2: Linea 2:
<<Indice(depth=2)>>
<<Informazioni(forum="http://forum.ubuntu-it.org/viewtopic.php?f=46&t=590616"; rilasci="14.04")>>
<<Indice(depth=1)>>
<<Informazioni(forum="http://forum.ubuntu-it.org/viewtopic.php?f=46&t=590616"; rilasci="24.04 22.04")>>
Linea 7: Linea 7:
'''Git''' è molto potente per quanto riguarda i '''branch''' (rami di sviluppo paralleli). Possiamo 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]].

= Branching =

 0. Spostati all'interno della cartella del progetto:{{{
'''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:{{{
Linea 18: Linea 38:
 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.

== 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 ==
Linea 33: Linea 69:
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:{{{
* 1412239 (HEAD, master, gp-1) - user : Aggiunta data in stampa. (2 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (5 minutes ago)
* e9ea39b - user : README aggiunto (12 minutes ago)
 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)
Linea 51: Linea 83:
== Modifiche al codice ==

 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>
int main() {
    std::cout << "Thu Dec 4 14:48:20 CET 2014: 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
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

 modified: src/main.cpp

no changes added to commit (use "git add" and/or "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).

Committiamo le modifiche e vediamo che succede nel log:

{{{
git commit -a -m "Modificato codice per issue gp-1."
[gp-1 d8b610a] Modificato codice per issue gp-1.
 1 file changed, 1 insertion(+)
git lg
* d8b610a (HEAD, gp-1) - user : Modificato codice per issue gp-1. (18 seconds ago)
* 1412239 (master) - user : Aggiunta data in stampa. (4 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (7 minutes ago)
* e9ea39b - user : README aggiunto (14 minutes ago)
}}}

Che e' successo? Il branch master, che e' quello su cui lavoravamo prima, e' rimasto inalterato (infatti e' rimasto al commit precedente), mentre nel nuovo branch e' stato memorizzato il commit appena creato. Ovviamente se proviamo ad eseguire il programma otteniamo l'output modificato con la nostra aggiunta:

{{{
make clean
rm -fr bin/ obj/
make
./src/main.cpp
mkdir bin
bin/main
Thu Dec 4 14:48:20 CET 2014: Benvenuti su Git!
Issue gp-1 implementata
}}}

Torniamo nel branch '''master''', rieseguiamo il programma e vediamo che succede:

{{{
== 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 <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 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 <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 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''':{{{
Linea 109: Linea 136:
Switched to branch 'master' }}}
 0. Eseguire nuovamente il programma:{{{
Linea 111: Linea 139:
rm -fr bin/ obj/
./src/main.cpp
mkdir bin
Thu Dec 4 14:48:20 CET 2014: Benvenuti su Git!
}}}

Come possiamo vedere, siamo ancora allo stato precedente, prima di eseguire il branch. A questo punto nel log si puo' vedere una cosa interessante:

{{{
git lg
* d8b610a (gp-1) - user : Modificato codice per issue gp-1. (2 minutes ago)
* 1412239 (HEAD, master) - user : Aggiunta data in stampa. (6 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (8 minutes ago)
* e9ea39b - user : README aggiunto (16 minutes ago)
}}}

Vi ricordate di '''HEAD'''? Adesso punta al commit '''master'''. HEAD quindi e' un puntatore al commit in cui attualmente ci troviamo. Possiamo andare in qualsiasi commit, non solo sugli ultimi dei rispettivi branch, digitando

{{{
}}}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:{{{
Linea 131: Linea 151:
}}}

dove {{{SHA1}}} e' il codice SHA1 del commit.

Adesso ci troviamo sul branch master. Supponiamo di voler aggiungere una cartella di documentazione:

{{{
mkdir doc
echo '== Changelog =='$'\n'$'\n''First release' > doc/Changelog
cat doc/Changelog
== Changelog ==

First release
}}}

Committiamo adesso la modifica e vediamo lo stato del nostro repository.

{{{
git add doc/
git commit -a -m "Aggiunta cartella documentazione."
[master e4064d8] Aggiunta cartella documentazione.
 1 file changed, 3 insertions(+)
 create mode 100644 doc/Changelog
git lg
* e4064d8 (HEAD, master) - user : Aggiunta cartella documentazione. (17 seconds ago)
| * d8b610a (gp-1) - user : Modificato codice per issue gp-1. (5 minutes ago)
|/
* 1412239 - user : Aggiunta data in stampa. (9 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (11 minutes ago)
* e9ea39b - user : README aggiunto (19 minutes ago)
}}}

Interessante. Possiamo notare come adesso i nostri due branch stiano prendendo strade parallele. Sono partiti da un punto in comune, ma ognuno sta avendo modifiche indipendenti.
}}}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.
Linea 169: Linea 189:
 * Il branch '''master''' ha aggiunto la documentazione.
 * Il branch '''gp-1''' ha implementato una feature.

Vogliamo adesso effettuare un '''merge'''. Cioe' vogliamo 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 e', molto fantasiosamente, {{{merge}}}. Il modo piu' diretto di utilizzare il comando e'

{{{
git merge altro_branch
}}}

Questo comando prende il branch '''altro_branch''' e introduce le sue modifiche sul branch corrente. Noi vogliamo effettuare il merge di '''gp-1''' su '''master'''. Quindi prima assicuriamoci di essere sul branch '''master''' (effettuiamo il checkout in caso non lo fossimo):

{{{
git branch
  gp-1
* master
}}}

Dopodiche', effettuamo il merge:

{{{
git merge gp-1
Merge made by the 'recursive' strategy.
 src/main.cpp | 1 +
 1 file changed, 1 insertion(+)
}}}

Che e' successo? Andiamo a vedere il log:

{{{
git lg
* f61b2e2 (HEAD, master) - user : Merge branch 'gp-1' (9 seconds ago)
|\
| * d8b610a (gp-1) - user : Modificato codice per issue gp-1. (7 minutes ago)
* | e4064d8 - user : Aggiunta cartella documentazione. (3 minutes ago)
|/
* 1412239 - user : Aggiunta data in stampa. (11 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (14 minutes ago)
* e9ea39b - user : README aggiunto (21 minutes ago)
}}}

Sono successe cose interessanti: come si puo' vedere, nel branch master e' stato creato un nuovo commit, che e' il commit di merge. Il suo commento dice che e' 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'''). Ci troviamo ancora nel branch master:

{{{
git branch
  gp-1
* master
}}}

Ma possiamo vedere che sono state include le modifiche del secondo branch:

{{{
cat src/main.cpp
#include <iostream>
int main() {
    std::cout << "Thu Dec 4 14:48:20 CET 2014: Benvenuti su Git!" << std::endl;
    std::cout << "Issue gp-1 implementata" << std::endl;
    return 0;
}
make clean && make && bin/main
rm -fr bin/ obj/
./src/main.cpp
mkdir bin
Thu Dec 4 14:48:20 CET 2014: Benvenuti su Git!
Issue gp-1 implementata
}}}

Abbiamo quindi creato un branch secondario, abbiamo applicato una issue in questo branch, e poi abbiamo riportato sul branch principale le modifiche.

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

 1. Si decide la issue da aggiungere/rimuovere/modificare.
 1. Dal branch principale (quale sia dipende dalla politica di gestione) si crea un nuovo branch, con un nome identificativo della modifica (puo' essere il codice associato a Bugzilla, ad esempio. Il nome '''gp-1''' e' un esempio di codice, infatti).
 1. Si lavora alla issue su quel branch.
 1. 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 tutti i casini che si vogliono sul proprio branch, senza andare ad inficiare quello principale che ne rimane immune fino a quando la issue non e' completamente testata e funzionante (si spera).

Se nel frattempo arriva un'altra issue piu' urgente un bug da risolvere o quant altro, si crea semplicemente un altro branch da quello principale, come fatto in precedenza, e si lavora su quello. I branch sono indipendenti fra di loro. Questo assicura grande flessibilita' nella gestione del progetto.

= Repository remoti =

Quello che abbiamo fatto finora permette di lavorare da soli, ma nella maggior parte dei casi occorre che diverse persone possano accedere al repository, lavorare su di esso e mettere le modifiche.

Simuliamo in locale questo comportamento. Occorre creare una nuova cartella dove vogliamo creare il nuovo repository:

{{{
mkdir /home/user/gitproject_2
cd /home/user/gitproject_2
}}}

Adesso possiamo procedere in due modi:

=== Clonazione repository ===

Possiamo clonare direttamente un repository, avendone quindi una copia locale:

{{{
git clone /home/user/gitproject .
Cloning into '.'...
done.
}}}

Il comando {{{clone}}} ha permesso di prendere il repository remoto (nel nostro caso quello precedente, ma potrebbe essere un repository su web o su un server), e l'abbiamo copiato nella cartella corrente (.). Infatti possiamo vedere il log del repository:

{{{
git lg
* f61b2e2 (HEAD, origin/master, origin/HEAD, master) - user : Merge branch 'gp-1' (4 minutes ago)
|\
| * d8b610a (origin/gp-1) - user : Modificato codice per issue gp-1. (11 minutes ago)
* | e4064d8 - user : Aggiunta cartella documentazione. (6 minutes ago)
|/
* 1412239 - user : Aggiunta data in stampa. (15 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (18 minutes ago)
* e9ea39b - user : README aggiunto (25 minutes ago)

}}}

Il log e' '''quasi''' uguale a quello originale. Si nota la presenza di altri branch:

 * origin/master
 * origin/HEAD
 * origin/gp-1

Questi sono i branch del repository remoto, che sono materialmente quelli creati nel repository originale. '''origin''' e' il nome di default che Git da ad un repository remoto, che possono essere elencati col comando '''remote'''

{{{
git remote
origin
}}}

Questo e' l'elenco dei repository remoti:

 * E' solamente uno perche' al momento abbiamo clonato uno gia' esistente
 * Si, Git puo' avere diversi repository remoti associato allo stesso repository locale. Questo permette molta flessibilita', ma al momento ignoriamo questo aspetto.
 
Abbiamo invece solamente un branch locale, '''master''', sincronizzato con il master remoto (piu' precisamente nel punto in cui punta HEAD remoto):

{{{
git branch
* master
}}}

=== Aggiunta manuale remote ===

Il secondo metodo consiste nell'aggiungere manualmente il repository remoto a quello attuale.

Creiamo quindi un repository vuoto:

{{{
mkdir /home/user/gitproject_3
cd /home/user/gitproject_3
git init
Initialized empty Git repository in /home/user/gitproject_3/.git/
}}}

Se vediamo la lista dei repository remoti, ovviamente e' vuota:

{{{
git remote
}}}

Aggiungiamo quindi il repository remoto, tramite il comando '''remote add''':

{{{
git remote add origin /home/user/gitproject
git remote
origin
}}}

Proviamo a vedere il log:

{{{
git lg
fatal: bad default revision 'HEAD'
}}}

Il repository e' vuoto!

{{{
ls -altr
drwxrwxr-x 22 user group 4096 Dec 4 15:06 ..
drwxrwxr-x 3 user group 4096 Dec 4 15:06 .
drwxrwxr-x 7 user group 4096 Dec 4 15:07 .git
}}}

Questo perche' e' stato aggiunto il repository remoto, ma non abbiamo ancora fatto la sincronizzazione. Per poter sincronizzare il repository locale con quello remoto, occorre scaricare le modifiche. Questo viene fatto in due modi.

=== Fetch e Pull ===

Si vuole prendere il contenuto del repository remoto e sincronizzare quello locale, in maniera da poter prendere le modifiche remote. Il comando {{{fetch}}} permette di scaricare in locale le modifiche remote, ma '''NON''' di applicarle.

{{{
git fetch origin
remote: Counting objects: 23, done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 23 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (23/23), done.
From /home/user/gitproject
 * [new branch] gp-1 -> origin/gp-1
 * [new branch] master -> origin/master
}}}

Abbiamo scaricato le modifiche remote, ma se guardiamo il contenuto della cartella, risulta essere ancora vuota:

{{{
ls -altr
drwxrwxr-x 22 user group 4096 Dec 4 15:06 ..
drwxrwxr-x 3 user group 4096 Dec 4 15:06 .
drwxrwxr-x 7 user group 4096 Dec 4 15:09 .git
}}}

Questo perche' abbiamo scaricato le modifiche (che stanno dentro .git) ma non abbiamo ancora sincronizzato il tutto. Dal log possiamo vedere meglio quello che e' successo:

{{{
git lg
* f61b2e2 (origin/master) - user : Merge branch 'gp-1' (10 minutes ago)
|\
| * d8b610a (origin/gp-1) - user : Modificato codice per issue gp-1. (17 minutes ago)
* | e4064d8 - user : Aggiunta cartella documentazione. (12 minutes ago)
|/
* 1412239 - user : Aggiunta data in stampa. (21 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (23 minutes ago)
* e9ea39b - user : README aggiunto (31 minutes ago)
}}}

Come possiamo vedere, ci sono i repository remoti, ma non quello locale su cui ci troviamo. E, dato che in quello locale non abbiamo ancora fatto niente, la nostra directory e' vuota.

Effettuamo allora il merge del branch locale con quello remoto, come abbiamo visto precedentemente, e vediamo che succede:

{{{
git merge origin/master
git lg
* f61b2e2 (HEAD, origin/master, master) - user : Merge branch 'gp-1' (11 minutes ago)
|\
| * d8b610a (origin/gp-1) - user : Modificato codice per issue gp-1. (18 minutes ago)
* | e4064d8 - user : Aggiunta cartella documentazione. (13 minutes ago)
|/
* 1412239 - user : Aggiunta data in stampa. (22 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (24 minutes ago)
* e9ea39b - user : README aggiunto (32 minutes ago)
}}}

Come possiamo vedere, adesso i due branch sono allineati (puntano allo stesso commit). D'altronde, se vediamo il contenuto della cartella, possiamo vedere che e' aggiornato:

{{{
ls -altr
total 32
drwxrwxr-x 22 user group 4096 Dec 4 15:06 ..
drwxrwxr-x 2 user group 4096 Dec 4 15:11 src
-rw-rw-r-- 1 user group 16 Dec 4 15:11 README
-rw-rw-r-- 1 user group 258 Dec 4 15:11 Makefile
-rw-rw-r-- 1 user group 10 Dec 4 15:11 .gitignore
drwxrwxr-x 8 user group 4096 Dec 4 15:11 .git
drwxrwxr-x 2 user group 4096 Dec 4 15:11 doc
drwxrwxr-x 5 user group 4096 Dec 4 15:11 .
}}}

Potevamo eseguire il tutto con un unico comando, {{{pull}}}. Questo racchiude in se' il {{{fetch}}} ed il {{{merge}}}, ed e' il comando solitamente utilizzato in questi casi. Ricreiamo il repository e vediamo che succede col {{{pull}}} (in una nuova cartella vuota). Il comando {{{pull}}} richiede il nome del repository remoto e il branch di cui fare l'update:

{{{
mkdir /home/user/gitproject_4
cd /home/user/gitproject_4
git init
Initialized empty Git repository in /home/user/gitproject_4/.git/
git remote add origin /home/user/gitproject
git pull origin master
remote: Counting objects: 23, done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 23 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (23/23), done.
From /home/user/gitproject
 * branch master -> FETCH_HEAD
git lg
* f61b2e2 (HEAD, origin/master, master) - user : Merge branch 'gp-1' (15 minutes ago)
|\
| * d8b610a - user : Modificato codice per issue gp-1. (22 minutes ago)
* | e4064d8 - user : Aggiunta cartella documentazione. (17 minutes ago)
|/
* 1412239 - user : Aggiunta data in stampa. (26 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (28 minutes ago)
* e9ea39b - user : README aggiunto (36 minutes ago)
}}}

Abbiamo quindi creato un repository, e sincronizzato il suo contenuto con un repository remoto.

= Pubblicazione modifiche locali =

Possiamo a questo punto effettuare delle modifiche nel nostro nuovo repository:

{{{
sed -i '4 a \\tstd::cout << "Modifica da un altro repository" << std::endl;' src/main.cpp
cat src/main.cpp
#include <iostream>
int main() {
    std::cout << "Thu Dec 4 14:48:20 CET 2014: Benvenuti su Git!" << std::endl;
    std::cout << "Issue gp-1 implementata" << std::endl;
    std::cout << "Modifica da un altro repository" << std::endl;
    return 0;
}
git commit -a -m "Aggiunta riga di output."
[master 0ed9a58] Aggiunta riga di output.
 1 file changed, 1 insertion(+)
git lg
* 0ed9a58 (HEAD, master) - user : Aggiunta riga di output. (15 seconds ago)
* f61b2e2 (origin/master) - user : Merge branch 'gp-1' (23 minutes ago)
|\
| * d8b610a (origin/gp-1) - user : Modificato codice per issue gp-1. (30 minutes ago)
* | e4064d8 - user : Aggiunta cartella documentazione. (26 minutes ago)
|/
* 1412239 - user : Aggiunta data in stampa. (34 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (37 minutes ago)
* e9ea39b - user : README aggiunto (44 minutes ago)
}}}

Abbiamo creato un nuovo commit, e dal log possiamo vedere che i due branch master, quello locale e quello remoto, non sono piu' (ovviamente) allineati. Per inviare al repository remoto le mostre modifiche, occorre utilizzare il comando {{{push}}}, specificando sempre il repository remoto e i branch da voler sincronizzare:

{{{
git push origin master
Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 395 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
To /home/user/gitproject
   f61b2e2..0ed9a58 master -> master
}}}


A questo punto abbiamo mandato nel repository remoto le nostre modifiche, in modo tale che gli altri utenti del repository, una volta sincronizzati con quello remoto, possano percepire le nostre modifiche.

{{{{#!wiki note
'''Errore push'''

A questo punto si potrebbe ottenere il seguente messaggio di errore:

{{{
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To ../gitproject/
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to '/home/user/gitproject'
}}}

Questo perche' il nostro repository remoto non e' di tipo '''bare'''. Al momento ignoriamo questo avviso e, per poter effettuare il push, digitare il seguente comando:

{{{
git config --global receive.denyCurrentBranch ignore
}}}

E poi rieseguire il push. Quando non e' piu' necessario settare lo stesso valore a '''refuse''':

{{{
git config --global receive.denyCurrentBranch refuse
}}}

per ripristinare lo stato originale.
}}}}

Per essere sicuri di aver fatto tutto correttamente, andiamo ad uno dei repository creato in precedenza:

{{{
cd /home/user/gitproject_3
}}}

Ed effettuiamo il pull per risincronizzarci col server remoto, che a questo punto avra' le nostre modifiche:

{{{
git pull origin master
From /home/user/gitproject
 * branch master -> FETCH_HEAD
Updating f61b2e2..0ed9a58
Fast-forward
 src/main.cpp | 1 +
 1 file changed, 1 insertion(+)
git lg
* 0ed9a58 (HEAD, origin/master, master) - user : Aggiunta riga di output. (4 minutes ago)
* f61b2e2 - user : Merge branch 'gp-1' (27 minutes ago)
|\
| * d8b610a (origin/gp-1) - user : Modificato codice per issue gp-1. (34 minutes ago)
* | e4064d8 - user : Aggiunta cartella documentazione. (30 minutes ago)
|/
* 1412239 - user : Aggiunta data in stampa. (38 minutes ago)
* e1e5a46 - user : Aggiunti sorgenti e Makefile (41 minutes ago)
* e9ea39b - user : README aggiunto (48 minutes ago)
}}}

= Conclusioni =

In questa breve guida sono stati esaminate le seguenti operationi:

 * Creazione repository vuoto
 * Clonazione repository
 * Commit di modifiche
 * Creazione branch
 * Merge di branch
 * Sincronizzazione con repository remoti.
 
Git permette di fare molte altre cose. La guida ufficiale che potete trovare sul [[http://git-scm.com/doc|sito ufficiale]]
e' molto esaustiva. Ovviamente e' possibile modificare il wiki per arricchirlo e correggerlo.
 * 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''':

 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 <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. [[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.
}}}


##<<Anchor(log_master)>>
##== 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]]
Linea 587: Linea 258:
CategoryProgrammazione CategoryHomepage CategoryProgrammazione


Guida verificata con Ubuntu: 22.04 24.04

Problemi in questa pagina? Segnalali in questa discussione

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:

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:

  1. Si decide la issue da aggiungere/rimuovere/modificare.
  2. 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).

  3. Si lavora alla issue su branch secondario.
  4. 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

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.

Spostarsi all'interno della cartella del progetto, digitando nel terminale il seguente comando:

cd gitproject

Visualizzazione branch attivi

Per visualizzare i branch attivi:

  1. Digitare nel terminale il comando:

     git branch

    verrà restituito:

      * master
    • 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.

  1. Per creare un nuovo branch col nome gp-1 digitare nel terminale il seguente comando:

     git branch gp-1
  2. 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

  1. 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'
  2. Verificare quale sia il branch attivo. L'output sarà:

      * gp-1
        master

    conferma che il branch attivo è ora gp-1.

  3. 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

  1. 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
  2. Visualizzare il contenuto modificato del file per verifica, digitando il comando:

     cat src/main.cpp

    che risulterà:

     #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;
     }
  3. 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 <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 si sta modificando il nuovo branch (il messaggio mostra il nome del branch su cui si sta lavorando).

  4. 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(+)
  5. 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:

  1. 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
  2. Tornare nel branch master:

    git checkout master
  3. 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.
  4. 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.

  1. Creare una directory di documentazione e un file Changelog, digitando nel terminale i seguenti comandi:

     mkdir doc
     echo '== Changelog =='$'\n'$'\n''First release' > doc/Changelog
  2. Visualizzare il contenuto:

     cat doc/Changelog

    che risulterà:

     == Changelog ==
    
     First release
  3. 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
  4. 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:

  1. Assicurarsi di essere nel branch di destinazione (master) tramite git branch.:

     git branch

    cioé che risulti:

       gp-1
     * master
  2. 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(+)
    • Il comando per effettuare i merge in Git sarà del tipo git merge MERGE

  3. 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;
     }
  4. 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).

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.

Ulteriori risorse


CategoryProgrammazione