Introduction

Git è un sistema di controllo versione distribuito (DVCS).

Il suo scopo principale è quello di tracciare e gestire le modifiche al codice sorgente di un progetto (o a qualsiasi insieme di file) nel tempo. In pratica, crea una "storia" completa del progetto, permettendo al team di:

  • Tornare a qualsiasi versione precedente.

  • Lavorare in parallelo senza sovrascrivere il lavoro degli altri.


Per Controllo Versione (o Version Control) si intende un sistema che registra le modifiche apportate a un file o un insieme di file nel tempo

Si può immaginare come una "macchina del tempo" per i file: ogni volta che salva una modifica, il sistema memorizza una "istantanea" del progetto. Questo ti permette di:

  1. Tornare a qualsiasi versione precedente.

  2. Visualizzare la storia completa di chi ha fatto cosa e quando.

  3. Gestire i contributi di più persone allo stesso file.

È un concetto fondamentale nello sviluppo software, ed è esattamente la funzione che Git svolge, ma in modo distribuito.


Alcuni esempi di comandi di Git

Per dirla semplicemente, quando si lavora con Git, una modifica passa attraverso tre fasi fondamentali, ognuna gestita da un comando chiave:

  1. Working Directory (La tua cartella di lavoro)

  2. Staging Area (L'area di preparazione)

  3. Local Repository (La storia salvata in locale)


I Comandi Fondamentali (Il Ciclo di Vita)

I comandi principali per la maggior parte del lavoro quotidiano sono:

Comando
Descrizione
Scopo

git init

Inizializza un nuovo repository Git in una cartella esistente. Questo crea la cartella .git che traccia tutte le modifiche.

Avviare il tracciamento di un progetto.

git add <file>

Sposta i cambiamenti di uno o più file dall'area di lavoro alla Staging Area.

Preparare i cambiamenti da salvare (il "carrello" dei cambiamenti).

git commit -m "Messaggio"

Salva in modo permanente i cambiamenti presenti nella Staging Area nel Repository Locale.

Salvare la versione con un'istantanea (commit) e un messaggio descrittivo.

C'è anche un quarto comando che ti sarà utilissimo:

  • git status: Mostra in quale stato si trovano i tuoi file: modificati, in staging, o non tracciati. È una sorta di bussola .


se clicco su una di queste commit , vedo cosaè stato modificato ecc

Controlliamo di avere installato git sul pc

Su mac/Linux si trova già installato :

git --version

Come installare git :


Apriamo visual studio code :

selezioniamo una cartella vuota : e facciamo il clone di una repository :

git clone nome_dELLA_REPOSITORY

Posso vedere i file nascosti con il comando ls -la

Posso usare il comando git status per vedere la situazione

se adesso vado a creare un nuovo file ad esempio index.html

lo devo "riportare in git" posso usare il comando

git add .

Il punto cosa mi indica ?

se voglio solamente un file specifico :

git add index.html
git commit -m "Aggiunto file html" -m "Descrizione del box"

Ho solamente salvato il codice in locale!

per inserirlo su git hub , devo usare il push!

git push

Devo configurare ssh!

ssh-keygen -t rsa -b 4096 -C "mia_email@gmail.com"

COMANDO GIT PUSH

Abbiamo appena completato il lavoro in locale e ora si vuole condividerlo. Il comando git push origin master è il cuore della collaborazione e del controllo versione distribuito di Git.

Questo comando indica al tuo Git locale di inviare i tuoi commit salvati a una destinazione specifica. Scomponiamo i tre elementi:

Componente
Spiegazione
Scopo

git push

L'azione. Significa "spingi" o "invia" le mie modifiche locali.

Invia i tuoi commit dal repository locale a quello remoto.

origin

L'alias (il "telecomando"). È il nome breve (convenzionale) che Git usa per identificare il tuo repository remoto (il server di destinazione, come su GitHub).

Specifica dove inviare i dati.

master (o main)

Il "ramo" (branch). Indica la linea di sviluppo specifica che stai inviando.

Specifica quale linea temporale di lavoro inviare.

Eseguendo questo comando, tutti i commit locali che sono stati creati con git commit vengono caricati sul server origin, aggiornando la versione del ramo master in quel luogo remoto.


Se invece voglio creare un progetto da zero ? Inizialize Repository

Creiamo un nuovo folder staccato dal precedente.

possiamo creare un documento README.md , e il comando che andiamo ad utilizzare è :

git init
git add .
git commit -m "ok"
git push 

Devo creare una repository :

Copio questo :

git remote add origin PASTE_CODE_git@....git
git remote -v
git push -u origin master 



Git Branching

Il Branching (o la creazione di "rami" ) è il concetto più potente e cruciale per la collaborazione in Git.

Immaginiamo un progetto come un singolo tronco d'albero (main o master). Quando si crea un ramo, è come far spuntare un ramo separato che si estende da quel tronco in un certo momento:

  • Scopo: Ti permette di lavorare su una nuova funzionalità (ad esempio, "login"), o correggere un bug, in un ambiente isolato. Nessuna delle modifiche che fai sul nuovo ramo influenzerà il codice sul ramo principale fino a quando non lo si decide.

  • Vantaggio: Il ramo principale resta stabile e funzionante, mentre si può sperimentare o sviluppare senza rischi.

Comandi per la gestione dei rami

Per gestire questo isolamento, i comandi fondamentali sono:

Comando
Scopo

git branch <nome-ramo>

Crea un nuovo ramo (una nuova linea temporale isolata).

git switch <nome-ramo>

Ti sposta su quel ramo, rendendolo il tuo ambiente di lavoro attivo.


git branch
git checkout -b feature-readme-instructions
  • git branch → mostra tutte le branch (rami) del repository e indica quella attualmente attiva con un asterisco.

  • git checkout -b feature-readme-instructions → crea una nuova branch chiamata feature-readme-instructions e passa automaticamente a quella branch.

se ora faccio nuovamente

git branch

posso notare che vedrò due branch

pe ritornare al master :

git checkout master
git checkout -b feature-readme-instructions

In visual studio code aggiungo un file o delle scritte al file.

git status
git add .
git commit -m "update file"
git checkout master
git diff feature-readme-instructions
git checkout feature-readme-instructions
git status
git push
git push -u origin feature-readme-instuctions


 
 
 

  • git status → mostra lo stato dei file (modificati, aggiunti o non tracciati).

  • git add . → aggiunge tutti i file modificati all’area di staging, pronti per il commit.

  • git commit -m "update file" → crea un commit con il messaggio "update file".

  • git checkout master → passa alla branch master.

  • git diff feature-readme-instructions → mostra le differenze tra la branch attuale e feature-readme-instructions.

  • git checkout feature-readme-instructions → torna alla branch feature-readme-instructions.

  • git status → di nuovo, controlla lo stato dei file nella branch corrente.

  • git push → invia i commit locali alla branch remota corrispondente.

  • git push -u origin feature-readme-instuctions → invia la nuova branch feature-readme-instuctions (notare il refuso nel nome) al repository remoto origin e imposta il tracciamento tra branch locale e remota.

posso anche scrivere

git push -u origin feature-readme-instuctions

PULL REQUEST PR

Una pull request (PR) è una richiesta di integrare le modifiche fatte in una branch (ad esempio una feature branch) dentro un’altra branch, di solito la main o master.

In pratica serve per:

  • proporre modifiche al codice;

  • farle revisionare da altri (code review);

  • discutere o correggere eventuali problemi prima dell’unione (merge).

Il flusso tipico è:

  1. Si crea una nuova branch e si fanno le modifiche.

  2. Si fa push della branch sul repository remoto.

  3. Su GitHub, GitLab o simili, si apre una pull request verso la branch principale.

  4. Dopo la revisione, la PR viene approvata e unita (merge) nel ramo principale.

SE GUARDO LA PARTE IN GIALLO!!

git checkout
git pull
git branch 

cancello il branch che non mi serve più

git branch -d feature-readme-instructions 
git branch


GESTIONE DEI CONFLITTI IN GIT ( MERGE CONFLICT )


Che cosa è un conflitto

Un conflitto (“merge conflict”) si verifica quando Git non riesce a unire automaticamente due versioni dello stesso file perché sono state apportate modifiche incompatibili nelle stesse righe (o quando un file è stato modificato in una branch e cancellato nell’altra, ecc.).

In questi casi Git interrompe il processo di merge (o rebase), segna i file che sono in conflitto e richiede un intervento manuale.


Flusso tipico di gestione dei conflitti

Ecco i passi principali:

  1. Avvia il merge o il rebase Ad esempio:

    git checkout master
    git merge feature-branch

    Oppure, se vuoi incorporare master dentro la tua feature:

    git checkout feature-branch
    git pull --rebase origin master
  2. Git segnala i conflitti Vedrai messaggi tipo:

    CONFLICT (content): Merge conflict in path/to/file.txt
    Automatic merge failed; fix conflicts and then commit the result.

    Inoltre git status mostrerà file come “Unmerged paths” o “both modified”. (Atlassian)

  3. Apri i file in conflitto e individua i marker All’interno dei file, troverai sezioni del tipo:

    <<<<<<< HEAD
    contenuto nel ramo corrente (ours)
    =======
    contenuto proveniente dal ramo che stai unendo (theirs)
    >>>>>>> feature-branch
    • La parte tra <<<<<<< HEAD e ======= è la tua versione locale (ramo corrente).

    • La parte tra ======= e >>>>>>> branch è l’altra versione (ramo che stai unendo).

    • Devi scegliere cosa tenere (tua versione, versione altrui, una combinazione) e rimuovere i marcatori <<<<<<<, =======, >>>>>>>. (GitHub Docs)

  4. Risolvere il conflitto Modifica manualmente il file per ottenere la versione desiderata, magari combinando parti di entrambe le versioni, riscrivendo un pezzo, ecc.

  5. Marcare il conflitto come risolto e fare commit

    git add path/to/file.txt

    Dopo aver “addato” tutte le modifiche risolte:

    git commit -m "Resolved merge conflict in …"

    Questo creerà il commit di merge (o continuerà il rebase) con la versione risolta. (GitHub Docs)

  6. (Se è un rebase) continuare il rebase Se stavi facendo git rebase, dopo aver risolto il conflitto ed effettuato git add, esegui:

    git rebase --continue

    Se vuoi abortire il rebase e tornare allo stato precedente:

    git rebase --abort
  7. (Se è un merge locale) push verso il remoto Se stavi unendo e tutto è andato a buon fine, fai:

    git push origin nome-branch

Comandi utili e strumenti

  • git status — per vedere i file in conflitto. (Atlassian)

  • git diff — mostra le differenze tra versioni e aiuta ad identificare cosa è cambiato. (Microsoft Learn)

  • git merge --abort — per interrompere il merge e tornare allo stato precedente (se vuoi annullarlo). (Atlassian)

  • git mergetool — per aprire uno strumento grafico (o visuale) per aiutarti a risolvere il conflitto. Può aprire un tool come vimdiff, meld, kdiff3, ecc. (Stack Overflow)

  • git checkout --ours path/to/file / git checkout --theirs path/to/file — comandi utili se vuoi scegliere interamente la versione “nostra” (ours) o “loro” (theirs) per un file conflittuale. Poi devi comunque git add e git commit. (nceas.github.io)


Strategie per ridurre la probabilità di conflitti

  • Integra spesso le modifiche del ramo principale nella tua feature branch (pull / rebase frequenti).

  • Evita modifiche grandi e macroscopiche in file condivisi; lavora con feature piccole e mirate.

  • Comunica con il team su quali file state toccando per evitare “step on toes”.

  • Usa convenzioni di codifica (indentazione, stile) uniformi: differenze di formattazione spesso causano conflitti “sporchi”.

  • Preferisci fare merge o rebase in modo controllato e spesso anziché grandi merge all’ultimo momento.

  • Se usi Pull Requests / Merge Requests, chiedi che la tua branch sia aggiornata con la base prima del merge.


JUMP IN

git branch
git checkout -b quick-test

git status
git diff
git add .
git commit -m "ok add something"
git checkout master

Cosa succede se modifico la stessa riga ?

cosa succede se provo a fare il merge ?

git branch
git checkout quick-test
git add .
git commit - m "add there"
git checkout quick-test
git diff master

ora provo a fare il MERGE!

git merge master

Modo più semplice è gestirlo in vs code :

Accept current change | Accept incoming change | accept both changes | ....

git status
git add . 
git commit -a "ok "


UNDOING IN GIT

In Git, “undoing” significa annullare o correggere operazioni come commit, aggiunte, merge o modifiche locali.


🧱 1. Annullare modifiche non ancora aggiunte (git add)

  • git checkout -- <file> → ripristina il file alla versione dell’ultimo commit (perde le modifiche non salvate).

    Esempio:

    git checkout -- index.html
  • git restore <file> (comando moderno equivalente).

    git restore index.html

📦 2. Rimuovere file dallo staging (dopo git add)

  • git reset <file> → toglie il file dallo staging area ma mantiene le modifiche nel working directory.

    git reset index.html
  • git restore --staged <file> → alternativa più recente e leggibile.

    git restore --staged index.html

🕒 3. Modificare l’ultimo commit

  • git commit --amend → permette di aggiungere/rimuovere file o modificare il messaggio dell’ultimo commit.

    git commit --amend -m "nuovo messaggio"

⚠️ Usare solo se il commit non è stato ancora pushato sul remoto.


⏪ 4. Tornare a un commit precedente

  • git reset → sposta il puntatore del branch a un commit precedente. Tre modalità principali:

    • --soft → mantiene tutto nello staging area.

    • --mixed → mantiene le modifiche ma toglie dallo staging area.

    • --hard → elimina tutte le modifiche successive.

    git reset --hard <commit-id>

⚠️ --hard è distruttivo: cancella definitivamente le modifiche non committate.


🧩 5. Annullare un commit senza perdere il lavoro

  • git revert <commit-id> → crea un nuovo commit che annulla le modifiche di quello indicato.

    git revert 7f6a3b2

    È il metodo sicuro da usare su branch già pubblicate (perché non riscrive la cronologia).


💥 6. Annullare un merge

  • git merge --abort → annulla un merge in corso e ripristina lo stato precedente.

    git merge --abort

📜 7. Visualizzare i commit per scegliere dove tornare

  • git log --oneline → mostra la cronologia compatta dei commit (utile per individuare l’ID del commit).

    git log --oneline

Situazione
Comando

Scartare modifiche locali

git restore <file>

Togliere file dallo staging

git restore --staged <file>

Modificare ultimo commit

git commit --amend

Tornare a un commit vecchio

git reset

Annullare commit pubblico

git revert

Fermare un merge

git merge --abort


Se viene commesso un errore e dobbiamo "tornare indietro"

Aggiungo qualcosa al README.md

git status
git add .
git status
git reset README.md
git status
git add .
git commit -m "add something"
git status

git reset HEAD~1

Il comando git reset HEAD~1 serve per annullare l’ultimo commit, ma senza perdere le modifiche ai file.


🔍 Significato dei componenti

  • git reset → sposta il puntatore della branch (HEAD) a un commit precedente.

  • HEAD~1 → indica “il commit prima dell’attuale” (cioè uno indietro).

    • HEAD = l’ultimo commit attuale

    • HEAD~1 = uno prima

    • HEAD~2 = due prima, e così via


⚙ Effetto pratico

Quando si esegue:

git reset HEAD~1

Git:

  1. rimuove l’ultimo commit dalla cronologia corrente;

  2. lascia le modifiche dei file nello staging area (pronte per essere ri-committate).


💡 Esempio

Supponiamo di avere:

git log --oneline
a1b2c3d (HEAD -> master) aggiunto file readme
e4f5g6h primo commit

E si esegue:

git reset HEAD~1

Ora:

git log --oneline
e4f5g6h primo commit

Il commit a1b2c3d è sparito dal log, ma i file che conteneva risultano ancora modificati nel working directory.


🧩 Varianti utili

  • git reset --soft HEAD~1 → annulla l’ultimo commit ma mantiene tutto in staging.

  • git reset --mixed HEAD~1 (default, cioè il comando che hai scritto) → annulla il commit e toglie i file dallo staging, ma li lascia modificati.

  • git reset --hard HEAD~1 → annulla il commit e cancella anche le modifiche (⚠️ irreversibile).


git log

mi copio il codice del commit :

git reset 15181...........be

Last updated