Guida a GIT
Guida a GIT
antonio mercurio
Buy on Leanpub

Dedica

Dedico questo libro a tutti gli sviluppatori opensource che ogni giorno ci forniscono software utile a farci risparmiare tempo e denaro. Ringrazio anche Linus Torvald per aver creato GIT.

Supporto

Per chiarimenti, suggerimenti o per comunicare qualsiasi errore potete scrivermi a tonymercurio75@gmail.com

Requisiti

Per capire questo libro non serve essere programmatori ma basta possedere un pc con Windows o Linux oppure un Mac. Basta sapersi spostare nelle cartelle da terminale, conoscere quindi i comandi base e sapere creare una cartella sulla propria macchina locale.

Cosa è GIT

Immaginiamo di dover lavorare ad un progetto con altri sviluppatori, ed ognuno lavora singolarmente sul proprio pc. Ogni sviluppatore avrà una copia di backup in locale del progetto. Ma che succede se ad un certo punto il responsabile del progetto che è distante dal team chiede di vedere l’avanzamento dello sviluppo?. Beh negli anni passati ci si spediva centinaia di email con le proprie modifiche. Tutto questo presenta l’ovvio svantaggio che è dovuto al fatto che le modifiche non sono sincronizzate e non risiedono in un luogo dove tutti le possono vedere contemporaneamente. Per questo si svilupparono negli anni dei sistemi centralizzati di Version Control. In pratica un team lavora ad un progetto e tutti i files risiedono su un server centrale, quindi tutti devono accedere a questo server per apportare modifiche o per vederle. Lo svantaggio è che se il server è down e non si ha una copia di backup si perde tutto in un attimo. Questo problema lo affrontò Linus Torvald inventore del kernel di Linux che utilizzava uno di questi server per le copie del kernel. Ad un certo punto inventò GIT. Esso si basa su un sistema decentralizzato di version control, in sostanza ogni sviluppatore ha una copia in locale detta repositorio e le modifiche che fa le committa e le invia ad un server remoto. Se il server remoto ad un certo punto è down si può facilmente recuperare l’ultima versione. Quando si vuole annullare una modifica locale si può facilmente ritornare sui propri passi e su una versione precedente.

Installazione

Git bisogna scaricarlo dal sito ufficiale sito. Da questa pagina scarichiamo la versione per il nostro sistema operativo. Per Windows c’è il file .exe che basta lanciare per l’installazione. Durante il processo di installazione scegliete sempre le opzioni già selezionate che vanno bene. Per linux per esempio Ubuntu basta digitare nel terminale questo comando sudo apt-get install git mentre per Mac c’è l’installer che potete lanciare tranquillamente.

Come creare un repositorio

Dobbiamo creare la configurazione di Git inserendo il nostro nome ed email che verranno inseriti nei repositori e saranno utili agli altri per capire chi ha apportato delle modifiche. Digitate questi comandi in sequenza

git config --global user.name="tony mercurio".

Questo comando serve ad inserire il vostro nome tra apici. Poi

git config --global user.email"tonymercurio75@gmail.com" .

Questo comando aggiunge la vostra email. Ora non dovrete più inserire questi comandi in seguito. La prima cosa da fare è creare sul proprio pc o mac una cartella con il nome del progetto in una posizione qualunque. Creiamo una cartella di nome progetti nella nostra cartella Documenti. Poi al suo interno creiamo una cartella per il nostro repositorio che chiamiamo test. Adesso da terminale spostiamoci in questa cartella cd Documents/progetti/test

Inizializzare un repositorio

Ora dobbiamo inizializzare il progetto con questo comando git init Ecco l’output nel terminale

git init
git init

Ora create nella cartella del progetto i seguenti files in formato testo prova1 prova2 prova3 ed inserite qualche parola in essi e salvate. Dobbiamo aggiungere tutti i files del progetto e farli tracciare da Git con questo comando git add . . Ora per vedere lo status del repositorio inseriamo questo comando git status e dovreste vedere questo risultato

git status
git status

Ora che i files sono tracciabili da Git dobbiamo eseguire un commit in questo modo git commit -m "primo commit" ed ecco il messaggio nel terminale

commit iniziale
commit iniziale

In sostanza ci dice che ha aggiunto al commit i nostri tre files. Dovete usare il suffisso -m al comando per inserire un messaggio utile per far capire di che modifica stiamo parlando. Il messaggio è quello che inserite fra apici. Ora inserite una parola qualunque nei tre files di testo e salvate le modifiche. Eseguite adesso il seguente comando git add . . Dovete sempre digitarlo prima di ogni commit. Ora vediamo lo status del repositorio git status. Ed ecco il messaggio nel terminale che ci avvisa delle modifiche apportate ai files e che devono essere committate.

git status 2
git status 2

Ora per salvare le modifiche eseguiamo il commit git commit -m "modifica ai files" . Il messaggio che inseriamo deve essere esplicito e chiarificante. Ora noterete questo messaggio

commit 2
commit 2

Per conoscere tutta la storia di un repositorio inserite questo comando git log . Ed ecco che ci fornisce informazioni sui commit che abbiamo eseguito fino ad ora e chi li ha eseguiti.

git log
git log

Per allenarci un pò eseguiamo altre modifiche ai file e poi di nuovo git add .

e a seguire il commit che chiamiamo terzo commit git commit -m "terzo commit"

Aggiungere files al repositorio in seguito

Nella cartella del progetto aggiungete un nuovo file di testo prova4 con del testo dentro. Poi facciamolo tracciare da git git add prova4.txt ed eseguiamo il commit git commit -m "aggiunto file prova4"

Creare un repositorio su Github

Andiamo sul sito github. Se non siete iscritti eseguite un’iscrizione gratuita al sito. In alto a destra cliccate sull’icona a croce e scegliete la voce new repository. Ecco cosa compare

github
github

Nella casella repository name dovete inserire il nome del repositorio che deve essere lo stesso di quello che abbiamo creato in locale e cioè nel nostro esempio test. Poi spuntate l’opzione public e cliccate sul pulsante in basso. Adesso dobbiamo sincronizzare il repositorio locale e questo remoto con questo comando a terminale git remote add origin https://github.com/tonyubuntu/test

cioè l’indirizzo web è quello del vostro account nel mio caso tonyubuntu e poi il nome del repositorio. Poi segue git push -u origin master . Il primo comando serve a sincronizzare i due repositori e dovete digitarlo solo adesso. Mentre il secondo serve ad inviare tutti i files e le eventuali modifiche, in pratica i commit. Ora aggiornate la pagina di github e notate che il repositorio remoto adesso ha tutti i files del nostro repositorio locale. Inoltre vi spiega anche le revisioni e modifiche apportate. Lo notate in figura

remoto 2
remoto 2

Il comando push contiene la parola orign che sta per repositorio master remoto e master che è il nostro locale.

Inviare modifiche al repositorio remoto

Eseguiamo una modifica al file prova1 del progetto in locale. Poi il comando git add . e poi git commit -m "modificato prova1" . Ora git push -u origin master e notiamo che anche il progetto remoto si modifica. Vi chiederà ogni volta che eseguite il push il nome utente e password di github. Cioè le vodtre credenziali.

Gitignore

Quando eseguite il comando git add . state facendo tracciare tutti i files del progetto anche quelli inutili. In genere quando sviluppate un progetto con qualsiasi linguaggio avete molti files di log, altri files che non sono importanti per il progetto. Per esempio files temporanei. Quindi è buona norma che nel vostro repositorio ci sia un file .gitignore che contiene tutti i files e cartelle da escludere. Per non digitarlo a mano possiamo avvalerci di esempi già predisposti da Github per molti comuni progetti suddivisi in linguaggi e frameworks. Visitate questa pagina gitignore. Per esempio clicchiamo su Laravel e nella pagina che compare ricopiate il codice mostrato in un file .gitignore. Comunque di solito se usate un framework come Laravel o altri hanno già un loro file .gitignore.

Controllare le modifiche ai files

Quando apportate delle modifiche potete comunque sapere che tipo di modifica è stata apportata sull’ultimo commit eseguito con questo comando git diff Per sapere invece tutte le modifiche git diff --staged Vi mostrearà tutte le modifiche ai files tracciati da Git.

Rimuovere un file dal tracciamento

Se durante un commit non vogliamo tenere traccia di un file possiamo spostarlo in uno status definito unstaged, cioè le modifiche non vengono tracciate. Eseguite questo comando git reset head prova4.txt. Da questo momento ogni volta che eseguiamo un commit, questo file verrà ignorato. Per rimuovere un file dalla cartella del progetto e rimuoverlo dal repositorio eseguiamo questo comando per esempio sul file prova4. git rm prova4.txt . Ora quando eseguirete delle modifiche e dei commit questo file non ci sarà. Eseguite il commit git commit -m "eliminato prova4" ora eseguite il push git push -u origin master .

Rinominare un file

Per rinominare un file del progetto per esempio il file prova1 eseguite questo comando git mv prova1.txt prova.txt. Poi git add . e poi git commit -m "rinominato prova1" e poi git push -u origin master

I branches

Quando creiamo il nostro repositorio all’inizio ed eseguiamo il nostro primo commit, Git crea un branch (ramo) predefinito chiamato master. Immaginiamo un puntatore che si sposta ogni volta che eseguiamo un commit, e si sposta sull’ultimo commit eseguito. Immaginate di aver eseguito tre modifiche nel tempo e qundi tre commit, Git crea con ogni commit una istantanea delle modifiche e si sposta con il puntatore sul terzo commit eseguito e precisamente lo fa sul branch master. Immaginate che il responsabile del progetto su cui state lavorando vi abbia chiesto una funzione che non volete includere nel progetto che avete appena terminato e che avete in remoto su github. Potete creare un branch che vi consente di lavorare sui file senza compromettere i files del branch master.

Creare un branch

Per creare un branch di nome testing digitate questo comando git branch testing

Ora dovete spostarvi sul branch appena creato per renderlo attivo con questo comando git checkout testing

Ora provate ad eseguire una modifica al file prova e da terminale digitate git add . e poi git commit --m "modifica prova branch testing" .

Ora provate a spostarvi di nuovo nel master e vedete che il file prova non ha l’ultima modifica appena eseguita, perchè stavate lavorando su una copia diversa del progetto ed isolata dal resto. Ecco a cosa servono i branches. Ora create un nuovo branch di nome testing2 git branch testing2

e poi git checkout testing2"

Modificate un file ed eseguite git add . e poi

git commit --m "testing2" .

Poi ripassate al branch master git checkout master . Dovreste vedere tutto come era prima.

Eseguire un merging dei branches

Supponiamo che le modifiche del branch testing2 non ci servano, allora possiamo eliminare questo branch. Spostiamoci prima nel branch master git checkout master poi digitiamo git branch -D testing2".

Ora il branch testing2 è eliminato. Adesso vogliamo unire il branch test al branch master. Assicuriamoci di essere nel branch master ed inseriamo questo comando git merge testing.

A questo punto potreste ricevere un messaggio di errore che vi parla di conflitti. Questo succede quando sia nel branch testing che nel branch testing2 abbiamo eseguito delle modifiche sullo stesso file come nel caso nostro su prova. Ora se aprite il file in questione dovreste trovare una sezione come questa

<<<<<<<<<<<Head



testing

In sostanza il testo che vedete subito sopra ai trattini è stato inserito con il branch testing2. Cancellate questo testo ed eliminate la sezione HEAD e le frecce e poi salvate. Ora dovrebbero rimanere solo le modifiche che abbiamo eseguito sotto branch testing. Adesso git add . e poi git commit --m "merge".

Ora rieseguite git merge testing. Eseguiamo il comando push per inviare in remoto il commit git push -u origin master.

Pushing dei branches in remoto

Quando eseguiamo dei branches in locale non sono sincronizzati in remoto. Per condividere con il team un branch eseguiamo il push git push origin testing . Cioè origin è il branch master remoto e testing è quello locale che vogliamo unire. Ora dovreste vedere in remoto una situazione del genere

branch remoto
branch remoto

Se visitate il link dovreste veder il branch master che è quello del progetto su cui state lavorando e il branch testing che contiene le funzioni su cui state lavorando e che avete incluso. Creiamo adesso un brache testing3 git branch testing3. Spostatevi in questo branch ed aggiungete un nuovo file alla cartella del progetto di nome testing3.txt ed inserite del testo. Adesso git add . e poi git commit --m "testing3".

Ora spostiamoci nel branch master e da qui eseguiamo il push in remoto del branch testing3 git push origin testing3. Ora il branch è on line ma non è compreso nel master, e quindi è una copia isolata che possiamo sfruttare per test senza compromettere l’orgine. Per sapere ogni momento in quale branch siamo eseguite questo comando git branch

Clonare da remoto

Git si presta la lavoro in team, ma lo scenario che abbiamo creato fino ad ora è di uno sviluppatore che ha realizzato un progetto in locale e vuole mantenere una copia di backup in locale e una versione fotocopia in remoto. Per fare ciò abbiamo eseguito i seguenti passaggi

1- Git init per inizializzare il progetto 2- Git add . per aggiungere i files (fase di stage) 3- Git commit –m per committare le modifiche. 4- git push -u origin master per inviare in remoto le nostre modifiche locali.

Può succedere però che un team abbia creato un progetto che si trova su github, e noi siamo entrati nel team giusto ora e vogliamo lavorare sullo stesso progetto senza intaccare l’originale ma lavorando su una nostra copia. In questo caso dobbiamo clonare il progetto originario.

Creazione progetto remoto da clonare

Fingiamoci il team che crea il progetto in remoto e che chiamiamo blog. Andiamo su github e creiamo un nuovo repositorio di nome blog. Adesso il nostro repositorio remoto ha il seguente url https://github.com/tonyubuntu/blog. Ora da terminale spostiamoci nella nostra cartella progetti. Poi digitiamo questo comando git clone https://github.com/tonyubuntu/blog.git .

Alla fine abbiamo clonato il progetto in una cartella blog dentro la cartella progetti. Nel nostro caso il repositorio remoto era vuoto e ci avvisa anche nel terminale. Ora spostatevi nella cartella blog che è stata clonata. Inseriamo in questa cartella un file di nome prova.txt e poi facciamolo tracciare da git

git add .

Poi git commit --m "primo commit". Subito dopo il push git push -u origin master. Ora il file prova è anche online.

Creiamo un branch in locale di nome testing git branch testing. Poi ci spostiamo in esso git checkout testing. Creiamo un file di nome testing.txt nella cartella del progetto. Subito dopo git add . e poi git commit --m "primo commit su testing". Ora git push origin testing così inviamo il branch in remoto.

Scaricare gli update eseguiti in remoto

Ora abbiamo clonato il repositorio in remoto facendone una copia in locale ed abbiamo modificato lo stesso ed inviato le nostre modifiche in remoto. Se vogliamo però scaricare le modifiche eseguite in remoto da altri ecco come fare. Eseguiamo prima delle modifiche in remoto sul progetto, per esempio create un nuovo file. Cliccate sul pulsante create new file e dategli un nome ed inserite un contenuto. Ora in locale spostatevi nel branch master e digitate questo comando git fetch origin master. Cioè intercettiamo le modifiche al branch master in remoto. Ora uniamo i due branch e li sincronizziamo git pull origin master.

Adesso quello che abbiamo modificato in remoto si ritrova uguale in locale. Questi comandi dovete eseguirli ogni volta che viene eseguita una modifica in remoto e vogliamo incorporarla in locale. Apportiamo una modifica da remoto al branch testing. Selezioniamo il nostro branch dalla finestra in alto

update-branch
update-branch

poi cliccate su uno dei file del branch e sul pulsante a destra a forma di matita. Eseguite delle modifiche al testo e da locale spostatevi nel branch testing e digitate git pull origin testing . Ora che siete nel branch testing in locale dovreste vedere la modifica eseguita in remoto.

Annullare delle operazioni

Spostiamoci nel nostro branch testing git checkout testing. Poi aggiungiamo un nuovo file al progetto di nome aggiunto.txt. Ora chiediamo di tracciarlo git add aggiunto.txt. Prima di eseguire il commit ci accorgiamo di non voler più farlo tracciare ma non lo vogliamo cancellare dal progetto. Allora eseguiamo questo comando git rm --cached aggiunto.txt. Il comando rm sta per cancellazione e cached significa che stiamo indicando di non tracciarlo ma senza eliminarlo. Non dovete eseguire nessun commit per salvare questa operazione. Quando eseguiremo dei commits questo file non verrà preso in considerazione.

Eliminare un file aggiunto

Torniamo sui nostri passi e facciamo tracciare il file git add aggiunto.txt. Ora però dobbiamo eseguire un commit git commit --m "aggiunto file". Adesso immaginiamo di voler eliminare proprio questo file dal repositorio allora dobbiamo eseguire questo comando git rm aggiunto.txt e poi git commit --m "eliminato file".

Annullare delle modifiche ad un file

Torniamo nel nostro branch master così git checkout master. Ora apportate una modifica ad un file qualunque. Poi includetelo nel tracciamento git add . Prima di eseguire il commit ci accorgiamo di aver commesso un errore e vogliamo annullare le modifiche al file. Lanciamo questo comando git reset HEAD prova.txt. In questo caso abbiamo spostato il file sullo stato Unstaged, cioè i cambiamenti non vengono tracciati. Ora dobbiamo lanciare questo comando per eliminare definitivamente ogni modifica al file git checkout prova.txt.

Annullare le operazioni di commit

Fino ad ora abbiamo visto come annullare le operazioni di tracciamento file e di modifiche prima di aver eseguito un commit. Eseguiamo una modifica ad un nostro file e poi eseguiamo git add . e poi git commit --m "modifica file". Ora per annullare eseguiamo git revert head~1. L’opzione revert inverte il nostro ultimo commit, in pratica fa il contrario del nostro ultimo commit che nel nostro esempio era la modifica di un file. Ora eseguite git commit --m "annullata modifica". Adesso quando eseguirete il push non ci sarà l’ultimo commit.

Annullare una operazione di push

Eseguiamo qualsiasi modifica sul nostro branch master e poi tracciamo i files con git add . . Ora eseguiamo il commit git commit --m "commit" ed infine il push git push -u origin master. Ora per tornare sui nostri passi eseguiamo git revert HEAD~1 e poi git push origin master.

indice dei comandi

  • git config –global user.name=”tony mercurio” (questo comando serve a configurare il nome usato nei commit)
  • git config –global user.email=”tonymercurio75@gmail.com” (questo comando serve a configurare la nostra email da usare nei commit)
  • git init (inizializza il repositorio)
  • git add nome file (aggiunge un file nuovo al tracciamento). L’operazione si chiama anche staging delle modifiche
  • git add . (aggiunge tutti i files al tracciamento senza distinzione)
  • git commit –m “messaggio” (serve a salvare le modifiche)
  • git mv prova.txt prova1.txt (serve a rinominare un file da prova a prova1)
  • git rm -cached prova.txt (serve a non far tracciare i cambiamenti al file anche senza cancellarlo)
  • git rm –f prova.txt (forza l’eliminazione del file dal repositorio). Eseguire poi il commit.
  • git reset HEAD prova.txt (serve a non prendere in considrazione una modifica eseguita su un file ).
  • git checkout prova.txt (segue il comando di cui sopra per eliminare le modifiche)
  • git revert HEAD~1 (riporta indietro al punto primo dell’ultimo commit)
  • git commit –a –m “messaggio” (modifica il messaggio all’annullamento del commit)
  • git revert HEAD~1 (se eseguito dopo un push sbagliato riporta indietro a prima di esso)
  • git push origin master (elimina il push in remoto dopo il revert precedente)
  • git remote add origin https://github.com/tonyubuntu/blog (serve a sincronizzare il nostro repositorio locale con quello remoto)
  • git push -u origin master (invia le modifiche dal nostro branch master a quello identico remoto)
  • git clone https://hithub.com/tonyubuntu/blog (serve a clonare in locale un repositorio remoto)
  • git merge origin master (serve a unire il repositorio remoto con il branch master locale dopo il clone)
  • git pull origin master (serve ad inviare i commit dal clone locale al remoto)
  • git branch testing (crea un branch di nome testing)
  • git checkout testing (ci spotiamo sul branch testing)
  • git branch (ci dice in quale branch ci troviamo)
  • git merge testing2 (consente di unire un branch testing2 al branch attivo)
  • git diff (consente di mostrare le differenze fra i files)
  • git log (mostra il log delle operazioni)
  • git fetch (serve a scaricare le modifiche da un repositorio remoto clonato)

Glossario

Riepiloghiamo alcuni termini usati nel libro.

  • GIT (Il nome usato dal version control system)
  • Version Control System (sistema per gestire il controllo delle versioni dei progetti)
  • HEAD (Possiamo definirlo come la posizione in cui si trova il puntatore al momento del commit)
  • Commit (Operazione di salvataggio delle operazioni)
  • Staging (Status di un file che si trova nella situazione di tracciamento da GIT)
  • Unstaged (file non tracciato)
  • Branch (Indica una nuova ramificazione o area di lavoro. Possiamo creare un branch per avere una copia sicura su cui lavorare senza comprometterem il branch originale)
  • Master (il nostro branch locale di default)
  • Origin (branch master remoto)
  • push (inviare i commit in remoto)
  • pull (sincronizzare le modifiche remote)