Lezione 14 di 35

Git 14

🔀 Git & GitHub · Modulo 3 · Lezione 14

Repository remoto 🌐

git clone · git push · git pull · git fetch · Origin · Collegare locale e remoto

⏱️ Durata stimata: 75–90 min 📊 Livello: Intermedio (Modulo 3) 🔧 Strumenti: Terminale · Account GitHub con SSH/HTTPS configurato 📋 Prerequisiti: Lezione 13 (account GitHub e autenticazione pronti)

🚀 Questa è la lezione che collega il tuo computer al mondo. Finora Git ha lavorato in locale — nessuno poteva vedere il tuo codice. Ora impari a creare un repository su GitHub, a inviare i tuoi commit con push, a scaricare le modifiche degli altri con pull, e a clonare un repository esistente. Alla fine di questa lezione, il tuo primo progetto sarà online su GitHub.

🎯 Obiettivi della lezione

  • Capire la relazione tra repository locale e repository remoto
  • Creare un repository su GitHub
  • Collegare un repository locale a GitHub con git remote add
  • Inviare i commit con git push
  • Scaricare un repository con git clone
  • Aggiornare il repository locale con git pull e git fetch
  • Capire cos’è origin e i tracking branch

📖 1. Teoria

1.1 — Locale vs remoto: il quadro completo

Finora hai lavorato con un repository locale — una cartella sul tuo computer con la cartella .git dentro. Un repository remoto è una copia del repository ospitata su un server (GitHub, GitLab, Bitbucket). Il remoto serve a due scopi: backup (se il tuo computer muore, il codice è salvo) e collaborazione (altri possono vedere e contribuire al progetto).

La relazione locale ↔ remoto
💻
Repository locale
Sul tuo computer
Working dir + staging + .git
Lavori qui ogni giorno
push →
← pull
← clone
🌐
Repository remoto
Su GitHub
Solo .git (no working dir)
Backup + collaborazione

1.2 — I 4 comandi fondamentali

Comando Direzione Cosa fa Quando
git clone remoto → locale Scarica l’intero repository (tutti i file + tutta la storia) Una volta, all’inizio — per scaricare un progetto
git push locale → remoto Invia i tuoi commit nuovi al repository remoto Dopo uno o più commit, per condividere il lavoro
git pull remoto → locale Scarica i commit nuovi dal remoto e li integra (fetch + merge) Prima di iniziare a lavorare, per avere l’ultima versione
git fetch remoto → locale Scarica i commit nuovi dal remoto senza integrarli Per vedere cosa c’è di nuovo senza toccare i tuoi file

📌 pull = fetch + merge. git pull è una scorciatoia: prima scarica i nuovi commit (fetch), poi li integra nel tuo branch corrente (merge). git fetch fa solo il primo passo — scarica ma non tocca i tuoi file. Fetch è più sicuro perché puoi controllare cosa è cambiato prima di integrare.

1.3 — Origin: il nome del remoto

Quando colleghi un repository locale a GitHub, Git dà un nome al remoto. Il nome predefinito è origin — è solo un’etichetta per l’URL del repository su GitHub. Puoi avere più remoti (lo vedrai con i fork nella Lezione 19), ma per ora ne basta uno.

# Vedere i remoti configurati
$ git remote -v
origin git@github.com:mario-rossi/mio-progetto.git (fetch)
origin git@github.com:mario-rossi/mio-progetto.git (push)
origin è il nome. L’URL indica dove si trova il repository su GitHub. (fetch) e (push) mostrano che lo stesso URL viene usato sia per scaricare che per inviare.
Quando scrivi git push origin main, stai dicendo:
git push
“invia”
+
origin
“a GitHub”
+
main
“il branch main”

1.4 — Due workflow: da zero vs da GitHub

Ci sono due situazioni comuni: creare un nuovo progetto e metterlo su GitHub, oppure scaricare un progetto che già esiste su GitHub.

Workflow A: locale → GitHub
Hai già un repository locale con commit. Vuoi metterlo su GitHub.
1. Crea repo vuoto su GitHub
2. git remote add origin URL
3. git push -u origin main
Workflow B: GitHub → locale
Un repository esiste già su GitHub. Vuoi scaricarlo per lavorarci.
1. Trova l’URL su GitHub
2. git clone URL
3. (origin è già configurato!)

1.5 — Creare un repository su GitHub

PASSO 1
Su GitHub, clicca il + in alto a destra → “New repository”.
PASSO 2
Scegli un nome per il repository (es. mio-primo-sito). Aggiungi una descrizione opzionale.
PASSO 3
Scegli Public (visibile a tutti) o Private (visibile solo a te e ai collaboratori che inviti).
PASSO 4
Se hai già un repo locale con commit: NON spuntare “Add a README file” — crea il repo vuoto. Se parti da zero su GitHub: spunta README.
PASSO 5
Clicca “Create repository”. GitHub mostra le istruzioni per collegare il repo locale.

⚠️ Errore comune: creare il repo su GitHub con README quando hai già commit locali. Se il repo GitHub ha un commit (il README) e il tuo repo locale ha commit diversi, le due storie divergono. Il primo push fallirà con errore. Per evitare il problema: se hai già un repo locale con commit, crea il repo GitHub vuoto (senza README).

1.6 — git push: inviare i commit

# Primo push: -u imposta il “tracking” (lo spiego dopo)
$ git push -u origin main
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Writing objects: 100% (9/9), 834 bytes | 834.00 KiB/s, done.
Total 9 (delta 2), reused 0 (delta 0)
To github.com:mario-rossi/mio-progetto.git
* [new branch] main -> main
branch ‘main’ set up to track ‘origin/main’.

# Dopo il primo push, basta:
$ git push
# Git sa già dove inviare grazie al tracking impostato con -u
Comando Quando Cosa fa
git push -u origin main Il primo push in assoluto Invia main a origin e imposta il tracking. -u = “upstream”.
git push Tutti i push successivi Invia i commit nuovi al remoto. Git sa già dove inviare.
git push origin feature/x Push di un branch specifico Invia il branch feature/x a origin (lo crea se non esiste).

1.7 — git clone: scaricare un repository

git clone scarica l’intero repository (tutti i file, tutti i commit, tutta la storia) dal remoto e crea una cartella locale con tutto già configurato — origin è già impostato, il tracking è già attivo.

# Clonare con SSH (consigliato)
$ git clone git@github.com:mario-rossi/mio-progetto.git

# Clonare con HTTPS
$ git clone https://github.com/mario-rossi/mio-progetto.git

# Clonare in una cartella con nome diverso
$ git clone git@github.com:mario-rossi/mio-progetto.git nome-cartella

Cloning into ‘mio-progetto’…
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
Receiving objects: 100% (15/15), done.
Resolving deltas: 100% (3/3), done.

📌 Dove trovare l’URL su GitHub: vai alla pagina del repository su GitHub → clicca il pulsante verde “Code” → scegli la tab SSH o HTTPS → copia l’URL. Se hai configurato SSH, usa l’URL SSH (git@github.com:...). Se usi token HTTPS, usa l’URL HTTPS (https://github.com/...).

1.8 — git pull e git fetch: aggiornare dal remoto

git pull (scarica + integra)
$ git pull
Scarica i commit nuovi dal remoto e li integra nel tuo branch corrente (fa un merge automatico). È l’operazione più comune — usala ogni mattina prima di iniziare a lavorare.
git fetch (scarica senza integrare)
$ git fetch
$ git log origin/main –oneline # vedi cosa c’è di nuovo
$ git merge origin/main # integra manualmente
Scarica i commit nuovi dal remoto ma non tocca i tuoi file. Puoi ispezionare le modifiche prima di integrarle. Più sicuro di pull, ma richiede un passo in più.
$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
Unpacking objects: 100% (3/3), done.
From github.com:mario-rossi/mio-progetto
a1b2c3d..d4e5f6a main -> origin/main
Updating a1b2c3d..d4e5f6a
Fast-forward
index.html | 3 +++
1 file changed, 3 insertions(+)
Git ha scaricato 3 nuovi oggetti e ha fatto fast-forward del tuo branch locale per allinearlo al remoto. I file sul tuo disco sono aggiornati.

1.9 — Tracking branch: origin/main

Quando fai fetch o pull, Git salva la posizione del branch remoto in un tracking branch — un riferimento locale che ricorda “dove si trova main sul remoto”. Si chiama origin/main.

# Dopo un fetch, puoi vedere la differenza tra locale e remoto
$ git log –oneline main ← il tuo branch locale
a1b2c3d Il mio ultimo commit

$ git log –oneline origin/main ← il branch remoto (dopo fetch)
d4e5f6a Commit del compagno
a1b2c3d Il mio ultimo commit

# origin/main è avanti di 1 commit — il compagno ha pushato qualcosa
$ git merge origin/main ← ora integra
Riferimento Cos’è Si aggiorna quando
main Il tuo branch locale Fai commit o merge
origin/main La “fotocopia” del branch main sul remoto Fai fetch o pull

1.10 — Riepilogo: il workflow quotidiano con GitHub

Ogni giorno con Git + GitHub
1. AGGIORNA
git pull
Scarica le novità dei compagni
2. LAVORA
Modifica, add, commit
Fai i tuoi commit locali
3. INVIA
git push
Condividi il lavoro
4. RIPETI
Ogni giorno
pull → lavora → push

💻 2. Esempi guidati

Esempio A — Portare un progetto locale su GitHub (Workflow A)

# === HAI GIÀ UN REPO LOCALE (dalle lezioni precedenti) ===
$ cd ~/Desktop/lab-merge # o qualsiasi repo con commit
$ git log –oneline -n 3 # verifica che ci siano commit

# === 1. CREA REPO VUOTO SU GITHUB (dal browser) ===
# github.com → + → New repository → nome: “lab-merge” → NO README → Create

# === 2. COLLEGA LOCALE E REMOTO ===
$ git remote add origin git@github.com:tuousername/lab-merge.git

# Verifica
$ git remote -v
origin git@github.com:tuousername/lab-merge.git (fetch)
origin git@github.com:tuousername/lab-merge.git (push)

# === 3. PRIMO PUSH ===
$ git push -u origin main
* [new branch] main -> main
branch ‘main’ set up to track ‘origin/main’.

# === FATTO! Vai su github.com/tuousername/lab-merge — il codice è online! ===

Esempio B — Clonare un repository da GitHub (Workflow B)

# Clona il repository che hai appena creato (simulando un compagno)
$ cd ~/Desktop
$ git clone git@github.com:tuousername/lab-merge.git lab-merge-clone
Cloning into ‘lab-merge-clone’…

$ cd lab-merge-clone
$ git log –oneline ← stessa storia del repo originale!
$ git remote -v ← origin è già configurato automaticamente!
origin git@github.com:tuousername/lab-merge.git (fetch)
origin git@github.com:tuousername/lab-merge.git (push)

Esempio C — Il ciclo push/pull tra due “sviluppatori”

# === “SVILUPPATORE 1” (nella cartella lab-merge) ===
$ cd ~/Desktop/lab-merge
$ echo “Nuova riga da dev1” >> index.html
$ git add . && git commit -m “Dev1: aggiunta riga alla home”
$ git push

# === “SVILUPPATORE 2” (nella cartella lab-merge-clone) ===
$ cd ~/Desktop/lab-merge-clone
$ git pull
Updating a1b2c3d..d4e5f6a
Fast-forward
index.html | 1 +

$ cat index.html
…
Nuova riga da dev1 ← la modifica è arrivata!

# Dev2 lavora e invia il suo lavoro
$ echo “Riga da dev2” >> index.html
$ git add . && git commit -m “Dev2: aggiunta altra riga”
$ git push

# Dev1 aggiorna per ricevere il lavoro di Dev2
$ cd ~/Desktop/lab-merge
$ git pull ← ora ha anche la riga di Dev2

🏋️ 3. Esercizi

🟢 Esercizio 1 — Il tuo primo push (Facile)

a) Prendi uno dei tuoi repository locali dalle lezioni precedenti (o creane uno nuovo con 3 commit).
b) Crea un repository vuoto su GitHub (senza README).
c) Collega: git remote add origin URL.
d) Verifica: git remote -v.
e) Push: git push -u origin main.
f) Vai su GitHub nel browser: il tuo codice è online? I commit sono visibili?

🔵 Esercizio 2 — Clone e pull (Medio)

a) Clona il repository dell’Esercizio 1 in un’altra cartella: git clone URL cartella-clone.
b) Nella cartella originale, fai una modifica, commit e push.
c) Nella cartella clone, fai git pull. La modifica è arrivata?
d) Nella cartella clone, fai una modifica, commit e push.
e) Nella cartella originale, fai git pull. La modifica è arrivata?
f) Hai appena simulato due sviluppatori che collaborano sullo stesso progetto!

🟠 Esercizio 3 — fetch vs pull (Medio)

a) Nella cartella originale, fai una modifica, commit e push.
b) Nella cartella clone, fai git fetch (non pull).
c) Esegui git log --oneline. Vedi il nuovo commit? (No — fetch non integra.)
d) Esegui git log --oneline origin/main. Ora lo vedi? (Sì — fetch ha aggiornato il tracking branch.)
e) Esegui git diff main origin/main. Vedi le differenze tra locale e remoto.
f) Integra con git merge origin/main. Ora git log --oneline mostra il commit?

🟣 Esercizio 4 — Push di branch (Difficile)

a) Nel tuo repo locale, crea un branch feature/test-remoto con 2 commit.
b) Pusha il branch su GitHub: git push -u origin feature/test-remoto.
c) Vai su GitHub: vedi il branch nel menu dropdown “branches”?
d) Nella cartella clone, fai git fetch. Poi git branch -a — vedi il branch remoto?
e) Switch al branch: git switch feature/test-remoto. Git crea automaticamente un tracking branch locale.
f) Fai una modifica, commit e push dalla clone. Poi nella cartella originale: git pull (sul branch feature). La modifica è arrivata?

❓ 4. Quiz di verifica

1. Qual è la differenza tra git clone e git pull?

Mostra risposta

git clone scarica l’intero repository da zero — tutti i file, tutti i commit, tutta la storia — e crea una nuova cartella locale. Si usa una volta sola, all’inizio, quando non hai ancora il repository. git pull scarica solo i commit nuovi dal remoto e li integra nel tuo branch corrente. Si usa ripetutamente per restare aggiornato con le modifiche degli altri. Dopo un clone, usi pull per aggiornare.


2. Cos’è origin?

Mostra risposta

origin è il nome predefinito che Git dà al repository remoto. È semplicemente un’etichetta che punta all’URL del repository su GitHub. Quando fai git push origin main, stai dicendo “invia il branch main al remoto chiamato origin”. Il nome “origin” è una convenzione — potresti rinominarlo, ma non c’è motivo di farlo. Puoi avere più remoti con nomi diversi (lo vedrai con i fork), ma nella maggior parte dei casi ne hai solo uno: origin.


3. Qual è la differenza tra git fetch e git pull?

Mostra risposta

git fetch scarica i commit nuovi dal remoto e aggiorna i tracking branch (origin/main), ma non tocca i tuoi file e non modifica il tuo branch locale. Puoi poi ispezionare le differenze con git log origin/main o git diff main origin/main prima di integrare. git pull è equivalente a git fetch + git merge origin/main — scarica e integra in un solo passo. Pull è più veloce, fetch è più sicuro perché ti dà il controllo su cosa viene integrato.


4. Fai git push e Git dice “rejected — non-fast-forward”. Cosa è successo?

Mostra risposta

Qualcun altro ha pushato commit sul remoto dopo il tuo ultimo pull. Il tuo branch locale è “indietro” rispetto al remoto — se Git accettasse il push, cancellerebbe i commit dell’altra persona. La soluzione: fai git pull per scaricare e integrare i commit nuovi (potrebbe esserci un merge o un conflitto), poi rifai git push. In pratica: prima allineati con il remoto, poi pusha. Questo errore è normale e frequente quando si lavora in team.


5. A cosa serve -u in git push -u origin main?

Mostra risposta

Il flag -u (abbreviazione di --set-upstream) imposta il tracking tra il tuo branch locale main e il branch remoto origin/main. Dopo averlo fatto una volta, Git “ricorda” dove deve inviare: i push successivi non hanno bisogno di specificare origin e main — basta scrivere git push. Lo stesso vale per pull: basta git pull senza argomenti. Il tracking viene impostato automaticamente anche quando fai git clone.


6. Hai creato un repo su GitHub con README e un repo locale con commit. Il primo push fallisce. Perché?

Mostra risposta

Perché il repository GitHub ha un commit (il README iniziale) e il tuo repository locale ha commit diversi — le due storie non hanno una base comune. Git rifiuta il push perché integrarle richiederebbe un merge che non è stato fatto. La soluzione più semplice: cancella il repository su GitHub, ricrealo vuoto (senza README), e rifai il push. In alternativa, puoi forzare con git pull origin main --allow-unrelated-histories per far fare il merge delle due storie indipendenti, poi push — ma è più pulito partire da un repo vuoto.


📚 Riepilogo della lezione

Cosa hai imparato oggi:
  • clone: scarica l’intero repo da GitHub (una volta sola, all’inizio)
  • push: invia i tuoi commit al remoto — git push -u origin main la prima volta, poi solo git push
  • pull: scarica e integra i commit nuovi dal remoto (= fetch + merge)
  • fetch: scarica senza integrare — più sicuro, ispezioni prima di fare merge
  • origin: il nome del remoto (l’URL di GitHub)
  • origin/main: il tracking branch — “dove si trova main sul remoto”
  • Workflow A: repo locale → repo vuoto su GitHub → remote add → push
  • Workflow B: repo su GitHub → clone → lavora → push
  • Quotidiano: pull → lavora → commit → push
  • Se push è “rejected”: fai pull prima, poi push

Prossima lezione →

Lezione 15 — README, licenze e .gitignore
Scrivere un buon README in Markdown. Scegliere una licenza.
Creare e personalizzare .gitignore per escludere file indesiderati.

Corso Git & GitHub · Per studenti e insegnanti · Lezione 14 di 45