Uno strumento di fondamentale importanza, che ha acquisito negli ultimi anni sempre più rilievo nel mondo dello sviluppo software, è il sistema di controllo versione distribuito.
Nel momento in cui un developer termina il proprio “task”, andando a risolvere eventuali bug o semplicemente andando ad introdurre all’interno del software stesso nuove feature, ha la necessità di gestire la cronologia di sviluppo e di tenere traccia dei movimenti fatti all’interno del codice. Grazie a GIT è possibile introdurre questa funzionalità in maniera semplice ed intuitiva.
INSTALLARE GIT
Installazione GIT Windows
Per avvalerci delle funzionalità del Git, in questa guida mostreremo brevemente l’installazione di una shell dedicata e sviluppata sulla base di quella dei classici sistemi Linux.
Tramite il progetto “Git for Windows” è possibile semplificare l’installazione tramite un semplice file eseguibile (.exe) che aggiungerà all’interno del proprio PC le funzionalità del Git in una console (o shell/terminale) dedicata.
Git for Windows fornisce un’”emulazione” di quella che è la classica console fornita con i sistemi Linux-like e permette l’accesso diretto a questa SHELL tramite un semplice clic sull’applicazione.
La procedura di installazione è molto semplice: una volta aperto l’installer, procedere selezionando eventuali personalizzazioni ed accettando le impostazioni dell’ambiente di lavoro, come mostrato nelle immagini sottostanti:
Alla fine dell’installazione ci troveremo di fronte alla nostra nuova CLI (Command Line Interface) con le proprietà del GIT installate:
Installazione GIT macOS
Tramite i recenti aggiornamenti dei sistemi operativi di casa Apple, è possibile installare Git direttamente da terminale.
Dopo aver installato homebrew (installer di pacchetti per macOS) basterà semplicemente digitare:
brew install git
premere INVIO e la procedura sarà terminata. Le feature del Git saranno disponibili nel terminale di macOS.
Installazione GIT Linux (Debian-Ubuntu):
Apriamo il terminale e tramite il comando
sudo apt-get update && sudo apt-get install git
attendiamo la fine dell’installazione.
Verifichiamo che tutto sia andato a buon fine con il comando “git –version” all’interno del terminale: apparirà la versione di git installata e la procedura sarà terminata.
GIT VERSIONING: COME FUNZIONA?
Come creare o clonare un repository con GIT:
Creazione:
Possiamo iniziare ad utilizzare le funzionalità di Git: vediamo, quindi, come creare un repository da un nostro progetto: spostiamoci, tramite la CLI, nella cartella del progetto in questione e digitiamo “git init” : in questa maniera verrà creata all’interno una cartella “.git” che conterrà i file e le informazioni essenziali del progetto. Da questo momento il git terrà traccia degli sviluppi (o modifiche) effettuati allo stesso.
Clonazione:
Per recuperare i dati/files di un progetto già esistente in una repository online, sarà necessario semplicemente eseguire il comando di clone.
git clone https://github.com/NOMEPROGETTO/NOMEPROGETTO.git
Piattaforme come Github o GitLab contenenti repository, permettono di gestire la clonazione con un semplice click, andando a copiare direttamente l’intero comando da ricopiare nel terminale.
In caso di clone effettuato correttamente visualizzeremo in console uno scenario di questo tipo:
Initialized empty Git repository in /root/NOMEPROGETTO/.git/
remote: Counting objects: 258593, done.
remote: Compressing objects: 100% (167/167), done.
remote: Total 258593 (delta 109), reused 0 (delta 0), pack-reused 258426
Receiving objects: 100% (258593/258593), 167.88 MiB | 7.01 MiB/s, done.
Resolving deltas: 100% (203882/203882), done.
Troveremo la cartella di progetto direttamente nella posizione in cui abbiamo effettuato il clone.
Gestire le commit:
Status:
Entriamo nella cartella del progetto che abbiamo appena inizializzato/clonato e digitiamo
git status
Tramite questo comando potremmo sempre conoscere il nostro allineamento verso il branch della repository in cui siamo; analizzeremo il termine branch successivamente quando andremo a spiegare le funzionalità delle ramificazioni del codice.
Grazie al comando di status potremmo vedere anche se siamo avanti allo status del branch, ovvero se ci sono modifiche che hanno aggiunto funzionalità al software ma che non sono state aggiornate nella repository, oppure indietro allo status del branch, cioè non abbiamo eseguito una pull di aggiornamento (altro termine che analizzeremo più avanti) per essere in pari con la repository.
Per aggiungere i file alle effettive modifiche ci basterà eseguire il comando (se ci dovessimo trovare nella cartella del progetto)
git add .
Salvare le modifiche fatte, effettuiamo una Commit:
Siamo arrivati al momento in cui andremo a salvare le nostre modifiche in un’istantanea tramite il comando di commit. Solitamente il comando viene eseguito con un messaggio, in modo tale da ricordare eventualmente cosa, “in teoria”, si è sviluppato.
Il comando da utilizzare è:
git commit -m'MESSAGGIO DEL COMMIT'
Analizzandolo, si può vedere come il “-m” sia riferito al messaggio da inserire nel virgolettato.
Una volta fatta la commit possiamo eventualmente verificare cosa abbiamo modificato, tramite il comando “git diff” che ci restituirà una situazione simile a questa:
diff –git a/index.php b/index.php
index 64b781c..156624f 100644
— a/testi index.php
+++ b/testi index.php
@@ -1,2 +1,2 @@
-testo rimosso
+righe aggiunte
Righe aggiunte 2
In alto vediamo il file che abbiamo modificato e, come si può ben intuire, la parte in rosso è quella rimossa, mentre in verde abbiamo le due righe che abbiamo aggiunto rispetto a quella che abbiamo cancellato.
Una volta eseguita, la commit rimane in memoria e può essere pushata; si possono effettuare tante commits prima di pubblicare eventuali modifiche nella repository.
Analizziamo ora il caso in cui noi decidessimo di eliminarne una fatta per errore: grazie al parametro –amend è possibile tornare indietro all’ultima commit eseguita per poi poterla modificare; quindi si usa il comando “git commit –amend”.
Ogni commit ha un suo valore di riferimento (o marker); quindi se avessimo un commit marcata “05f32d4”, potremmo vederne il contenuto con il comando “git checkout 05f32d4”.
Tornare indietro ad una vecchia commit:
Se volessimo ripristinare lo stato del codice ad una vecchia commit, basterà eseguire nel terminale il comando “git revert 05f32d4” (05f32d4 è il codice d’esempio usato già in precedenza”.
Pull e Push GIT:
Una volta terminate le modifiche apportate al codice, è necessario effettuare l’aggiornamento verso la repository, e quindi “spingerle” (push) verso di esso. Nel caso in cui ci fosse stata qualche modifica da parte di un altro sviluppatore, ci basterà “tirarle” (pull) verso di noi.
I comandi sono ovviamente:
git pull
git push
Gestione dei Branch:
Prima di passare alla gestione dei branch, ricordiamo come essi non siano altro che delle diramazioni del codice sviluppato: in un progetto, ci possono essere tante versioni di un unico file, delle “realtà alternative” al branch principale (master). In questo modo si riesce a lavorare su diverse funzionalità se un unico progetto con la possibilità di testare le nuove funzionalità sviluppate prima di pusharle nel master branch. Come si può ben intuire, questa funzionalità permette agli sviluppatori di potersi dividere i compiti con una minor possibilità di conflitti nel caso in cui si stia sviluppando su un file comune.
Prima di lavorare su un branch diverso, ricordiamoci che sarà necessario committare/pushare le eventuali modifiche rimaste in sospeso.
Creazione del branch
Per poter creare un branch utilizzeremo il comando “git branch NOMEBRANCH” e ci sposteremo su quella versione tramite il comando di checkout “git checkout NOMEBRANCH”.
Da questo momento sarà possibile eseguire tutti i comandi precedentemente descritti per sviluppare in una diramazione differente.
Aggiornamento dei branch:
Ogni volta che qualcuno avrà creato un nuovo branch, sarà necessario eseguire il comando
git fetch
per poter aggiornare la lista dei branch, che sarà visibile tramite “git branch”.
Eliminazione del branch:
Ovviamente sarà possibile eliminarne uno aggiungendo il paramentro “-d” davanti al nome:
git branch -d NOMEBRANCH
Merge di due branch:
Una volta terminate le modifiche su un branch, sarà possibile fare il merge tra quest’ultimo ed un altro (ad esempio il master). Per poter fare ciò, occorre usare il comando “git merge NOMEBRANCH”. Questo comando eseguirà l’operazione senza lasciarne traccia nella repository; per evitare che ciò avvenga è opportuno utilizzare il comando esteso:
git merge --no-ff NOMEBRANCH
dove il “-no-ff” crea un commit apposita per il merge.
NB: Con questo comando si esegue il merge del branch scelto con il Branch con cui si sta attualmente lavorando.
In caso di riscontro positivo, otterremo un risultato di questo tipo:
$
git checkout master
Switched to branch 'master'
git merge NOMEBRANCH
Updating 14f3ced..dc8c7f7
Fast-forward
test.txt | 0
test2.txt | 2 +-
2 files changed, 1 insertion(+), 1 deletion(-)
create mode 100644 test2.txt
Risoluzione di un conflitto in GIT:
Nel momento in cui durante l’operazione viene rilevato un conflitto, git ci avvertirà che sarà necessario un nostro intervento per risolvere quelle che sono le “Incoming changes” (le nostre modifiche) e le “Actual Changes” (quelle già presenti). Modificando il file, noteremo che ci saranno dei delimitatori, “<<<<<<<” e “========”:
<<<<<<< HEAD: NOMEFILE.estensione
Alice cominciava a sentirsi assai stanca di sedere sul poggetto accanto a sua sorella, senza far
niente: aveva una o due volte data un'occhiata al libro che la sorella stava leggendo, ma non v'erano
né dialoghi né figure, – e a che serve un libro, pensò Alice, – senza dialoghi né figure?
=======
La buca della conigliera filava dritta come una galleria, e poi si sprofondava così improvvisamente
che Alice non ebbe un solo istante l'idea di fermarsi: si sentì cader giù rotoloni in una specie di
precipizio che rassomigliava a un pozzo profondissimo.
>>>>>>> test:test.txt
Il testo compreso tra <<<<<<< e ======= è quello che avevamo nel ramo principale, ma che nel momento della fusione Git ha trovato il testo compreso tra ======= e >>>>>>> nel ramo test e non ha saputo cosa fare. Non ci resta che risolvere manualmente il conflitto modificando questa zona del file, salvare e usare “git add NOMEFILE.estensione” per dirgli che il conflitto è stato risolto e che ora, dopo una commit di conferma, effettuare il merge tra i branch.
Altro comando utile per vedere la lista dei branche che non hanno effettuato la fusione: “git branch –no-merged”;
Conclusioni:
Dopo aver seguito questa guida riassuntiva, si è sicuramente pronti per iniziare a gestire una repository in modo autonomo; concludiamo lasciando nell’immagine sottostante un piccolo recap dei comandi principali del Git: