Git essenziale: i comandi che usi davvero
Git non è GitHub. I comandi che usi davvero: clone, commit, branch, merge, pull e push. Più .gitignore, messaggi chiari e i file da non committare mai.
Indice
- Introduzione
- Perché Git esiste
- Annullare
- Collaborare
- Capire chi ha cambiato cosa
- Git non è GitHub (né GitLab)
- Il ciclo di lavoro quotidiano
- clone
- status
- add
- commit
- log
- Branch, switch e merge
- branch
- switch
- merge
- Quando un ramo ha senso
- Quando è rumore
- pull e push
- pull
- push
- .gitignore
- Un buon messaggio di commit
- Cosa non committare mai
- Force push: il comando che fa danni
- Autenticazione verso il remote
- Problemi comuni
- "origin does not appear to be a git repository"
- "Your branch is behind"
- "Please tell me who you are"
- Ho committato sul ramo sbagliato
- Il merge è un disastro
- Conclusione
Introduzione
Git serve a tre cose: tornare indietro, lavorare in più persone, capire chi ha cambiato cosa. Il resto è rumore.
Non ti serve la storia di Linus Torvalds. Non ti serve memorizzare cinquanta comandi. Ti serve un ciclo di lavoro che non ti faccia perdere codice, e la disciplina di non pubblicare segreti.
In questa guida trovi solo quello che usi davvero:
- perché Git esiste (annullare, collaborare, blame)
clone,status,add,commit,logbranch,switch,mergepullepush.gitignore- come si scrive un commit decente
- cosa non finisce mai in un repository
- perché
push --forceè un'arma, non una scorciatoia
Git è il programma sul tuo PC. GitHub e GitLab sono siti che ospitano una copia remota. Confonderli è il primo errore, e costa tempo.
Perché Git esiste
Senza versionamento, il lavoro vive in una cartella. Sovrascrivi un file. Il collega ha un'altra copia. Dopo due settimane nessuno sa quale sia quella giusta.
Git tiene la storia. Ogni commit è uno snapshot. Puoi confrontare, tornare indietro, isolare un esperimento su un ramo. Non è magia. È un diario del codice, con data e autore.
Annullare
Hai rotto qualcosa. Non è la fine. Se hai committato prima della modifica, puoi vedere il diff e ripristinare. Se non hai committato, status e restore ti dicono cosa è ancora recuperabile.
Senza commit, Git non ha memoria. Salvare il file non basta. Devi registrare lo stato.
Collaborare
Due persone sullo stesso progetto senza Git si passano zip e "versione_finale_2_davvero". Con Git ognuno lavora sul proprio clone. I rami tengono gli esperimenti separati. Il merge unisce. I conflitti si vedono, non si nascondono in una copia "quasi uguale".
Capire chi ha cambiato cosa
git blame (e la vista History su GitHub/GitLab) mostra chi ha toccato una riga e in quale commit. Non è un processo. È un modo per chiedere alla persona giusta, o per capire perché quella riga esiste.
Git non ti protegge se non committi. Il diario si scrive. Altrimenti resta una cartella come le altre.
Git non è GitHub (né GitLab)
Usi Git in locale anche senza account. init, add, commit, log funzionano su un disco, da soli.
GitHub, GitLab, Gitea, Bitbucket sono remote: un altro computer che tiene una copia del repository. Servono a condividere, fare backup fuori dal portatile, aprire merge request, gestire issue.
Il flusso è questo:
- lavori in locale
- committi in locale
pushverso il remote- gli altri
pullda quel remote
Se il remote sparisce e hai solo il laptop, hai ancora la storia. Se il laptop muore e non hai mai fatto push, la storia muore con lui.
| Cosa | Cos'è | Cosa non è |
|---|---|---|
| Git | Programma di versionamento, sul tuo PC | Un sito, un account, un'azienda |
| Repository (repo) | Cartella con la storia (directory .git) | "Il progetto su GitHub" in sé |
| Remote | Copia su un altro host (origin) | Git |
| GitHub / GitLab | Hosting + interfaccia + permessi | Il versionamento |
| Commit | Snapshot registrato, con messaggio | Salvare il file |
| Branch | Linea di storia parallela | Una cartella duplicata a mano |
"L'ho caricato su GitHub" non è un backup se il repo è solo lì e nessuno ha un
clone aggiornato. E "l'ho committato" non significa che sia sul remote: serve
push.
Il ciclo di lavoro quotidiano
Apri il terminale nella cartella del progetto. Quasi tutto passa da cinque comandi.
clone
Prendi una copia completa del repository, storia inclusa.
git clone [email protected]:esempio/progetto.git
cd progetto
L'URL SSH (git@…) è quello che userai se hai chiavi SSH. L'URL HTTPS chiede token o password. Per il lavoro di tutti i giorni, SSH è meno fastidioso.
clone crea la cartella, scarica i commit, imposta origin come remote. Non cloni ogni mattina. Cloni una volta. Poi pull.
Se il progetto è già sul disco e ha la cartella .git, sei già dentro un
repo. Non cloni di nuovo sopra. Entri e lavori.
status
È il comando che usi di più. Mostra tre cose: file modificati, file in staging, file non tracciati.
git status
Prima di add e commit, lanci status. Dopo un merge, lanci status. Se qualcosa "non torna", lanci status. Costa un secondo. Evita commit accidentalmente vuoti o pieni di file sbagliati.
add
Sposti le modifiche nell'area di staging: quello che entrerà nel prossimo commit.
git add file.txt
git add src/
git add -p
add su un singolo file è preciso. add src/ è comodo se quella cartella è il pezzo che stai chiudendo. add -p (patch) ti fa scegliere i pezzi: utile quando hai mescolato due lavori nello stesso file.
# Evitalo come abitudine
git add .
git add . prende tutto quello che è in cartella, tranne ciò che è in .gitignore. Se il ignore è fatto male, ci finiscono dump, build, .env. Su un repo piccolo e pulito può bastare. Su un repo vero, è pigro.
Staging esiste per un motivo: un commit deve contenere una cosa sola. Non "tutto quello che era sporco sul disco".
commit
Registra lo snapshot. Messaggio obbligatorio. Senza messaggio Git si rifiuta, o apre l'editor.
git commit -m "Fix timeout sul login se il provider OIDC non risponde"
-m va bene per una riga. Se ti serve il corpo (perché, come testare, cosa non hai toccato), usa git commit senza -m e scrivi nell'editor.
git commit -am "…" fa add+commit solo sui file già tracciati. I file nuovi restano fuori. Non è un sostituto di status.
log
Leggi la storia.
git log --oneline -20
git log --oneline --graph --decorate -20
--oneline è quello che serve al 90%. Hash corto, titolo del commit. Se il titolo è "fix" o "update", il log è inutile. Torneremo sui messaggi.
Per un file:
git log --oneline -- percorso/del/file
Branch, switch e merge
Il ramo main (a volte master) è la linea che consideri stabile. I rami di lavoro servono a non mischiare un esperimento con il codice che già gira.
branch
git branch
git branch feature/export-csv
Senza argomenti, elenca. Con un nome, crea. Creare non ti sposta: resti dove eri.
Un nome di ramo deve dire cosa stai facendo. feature/export-csv si capisce. pippo e nuovo no. Tra sei mesi il ramo è ancora lì, e nessuno sa se si può cancellare.
switch
git switch feature/export-csv
git switch -c feature/export-csv
switch ti sposta. -c crea e sposta in un colpo. checkout fa le stesse cose, ma fa anche altro: è più facile sbagliarlo. Per cambiare ramo, usa switch.
Git ti blocca lo switch se hai modifiche che andrebbero in conflitto sul ramo
di destinazione. Non forzare. Committa, oppure stash se sai cos'è. Se non lo
sai, committa su un ramo temporaneo.
merge
Riporti un ramo dentro un altro. Di solito: sei su main, unisci il ramo di lavoro.
git switch main
git pull
git merge feature/export-csv
Se Git può unire da solo, lo fa (fast-forward o merge commit). Se due commit hanno toccato le stesse righe in modo diverso, hai un conflitto. I file segnati vanno aperti, puliti, poi:
git add file-risolto.ts
git status
git commit
Il commit di merge chiude l'unione. Non lasciare marker di conflitto nel codice. status deve tornare pulito.
Quando un ramo ha senso
- Una feature che non è pronta
- Un fix isolato da non mischiare
- Un esperimento che potresti buttare
Quando è rumore
- Un commit sul
maindi un repo solo tuo - Dieci rami aperti e nessuno sa quali sono vivi
- Merge a catena senza
pullprima
pull e push
Qui entra il remote. Di solito si chiama origin.
pull
Scarichi i commit che gli altri (o tu, da un altro PC) hanno già mandato sul remote, e li integri nel ramo corrente.
git pull
pull è fetch + merge (o rebase, se l'hai configurato così). Prima di iniziare a lavorare, pull. Prima di un merge su main, pull. Prima di un push, se lavori in due sullo stesso ramo, pull.
Se pull fallisce per conflitti, è lo stesso lavoro del merge: apri i file, sistema, add, commit.
push
Mandi i tuoi commit sul remote.
git push
git push -u origin feature/export-csv
-u (upstream) la usi la prima volta su un ramo nuovo. Dopo, git push basta.
Push non è "salva su internet". Push pubblica la storia che hai committato. Se nel commit c'è un .env, sul remote c'è un .env. Toglierlo dal commit successivo non lo toglie dalla storia.
Locale e remote divergono. status dopo pull e push ti dice se sei
avanti, indietro, o in conflitto. Non indovinare.
.gitignore
File di testo nella radice del repo. Ogni riga è un pattern da non tracciare.
node_modules/
.env
.env.*
!.env.example
dist/
*.log
.DS_Store
.env.example (chiavi vuote o fittizie) può stare nel repo. Il .env vero no.
gitignore non toglie un file già committato. Se node_modules è nella storia, aggiungerlo al ignore ferma solo i commit nuovi. Per toglierlo dalla storia serve un lavoro a parte, e se il repo è già condiviso è doloroso. Meglio non committarlo la prima volta.
git status --ignored
Ti mostra cosa Git sta ignorando. Utile quando "manca un file" e in realtà è nel ignore.
Cosa finisce quasi sempre in .gitignore
Dipendenze installate (
node_modules,vendor)Build e cache (
dist,.next,pycache)Segreti e ambiente (
.env, chiavi, certificati)- Log, dump, backup locali
File del sistema (
.DS_Store,Thumbs.db)
Un buon messaggio di commit
Il log è documentazione. Se i titoli sono "fix", "wip", "aaaa", tra un mese non sai cosa è successo. blame diventa un elenco di rumore.
Una riga, all'imperativo, che dice cosa cambia e perché conta:
Limita a 3 i tentativi di login prima del lockout
Il form ritentava in loop sul 401 e bloccava l'account IdP.
La prima riga sta sotto i 72 caratteri. Il corpo (se serve) spiega il motivo, non ripete il diff. Il diff si vede già con git show.
| Debole | Meglio |
|---|---|
fix | Corregge il timeout del webhook Stripe |
update | Aggiorna Next a 16.2 per il fix del middleware |
vario | due commit, uno per tema |
modifiche varie e file env | non committare l'env; spezza il resto |
Non serve Conventional Commits se siete in due e vi capite. Serve se il team è più grande o se i changelog li genera una macchina. In ogni caso: un commit, un argomento.
"WIP" sul tuo ramo, prima di pranzo, succede. Prima di un merge su
main, riscrivi o fai squash. Il main si legge.
Cosa non committare mai
.env, file .pem, token, dump del database, backup, chiavi SSH private. Se un file permette di entrare da qualche parte, non sta nel repo.
# Controlla cosa stai per committare
git status
git diff --cached
--cached è il diff dello staging. Leggilo. Se vedi AWS_SECRET o DATABASE_URL=postgres://…, togli il file, aggiungilo al .gitignore, ricomincia il commit.
Un segreto committato e pushato è un segreto bruciato. Toglierlo dal commit successivo non basta: resta nella storia. Ruota la chiave, il token, la password. Poi, se serve, pulisci la storia. In quest'ordine.
Lo stesso vale per dati personali (export clienti, fogli paga, dump). Un repo privato su GitHub non è un caveau. Ha permessi, ha collaboratori, ha fork, ha CI che a volte stampa i log.
Force push: il comando che fa danni
git push --force
git push --force-with-lease
Riscrive la storia sul remote. I commit che c'erano possono sparire dalla punta del ramo. Chi aveva già fatto pull si trova un albero che non coincide più.
Lo usi solo sul tuo ramo, se sei solo, e sai perché (rebase, correzione di un commit appena fatto, non ancora usato da altri). Non lo usi su main. Non lo usi "perché pull dà conflitto". Il conflitto si risolve. Non si cancella.
--force-with-lease è meno cieco: rifiuta se sul remote c'è un commit che non hai. È il minimo, se proprio devi.
push --force su un ramo condiviso è il modo più veloce per far
sparire il lavoro di qualcun altro. Se non sai spiegare perché ti serve, non
lo lanciare.
Autenticazione verso il remote
HTTPS con password dell'account, su GitHub, non funziona più da anni. Serve un personal access token, oppure SSH.
SSH è il percorso pulito: una chiave sul PC, la pubblica sull'account, [email protected]:… come URL. Come si genera e si carica è in chiavi SSH.
# Verifica che Git veda il remote
git remote -v
Se origin è HTTPS e ogni push chiede credenziali, cambia URL:
git remote set-url origin [email protected]:esempio/progetto.git
Poi un git fetch di prova. Se chiede la passphrase della chiave, è il comportamento atteso. Se chiede la password di GitHub, l'URL o la chiave non sono a posto.
Problemi comuni
"origin does not appear to be a git repository"
Non c'è un remote, o l'URL è sbagliato. git remote -v. Se è vuoto, aggiungi origin. Se l'URL è copiato male (https su SSH, typo nell'org), correggilo con set-url.
"Your branch is behind"
Qualcun altro ha fatto push. git pull. Poi lavori. Poi push. Non force.
"Please tell me who you are"
Git non ha nome e email su quella macchina. Servono per il commit, restano nella storia.
git config --global user.name "Nome Cognome"
git config --global user.email "[email protected]"
Usa l'email che vuoi vedere nei commit. Su GitHub, quella associata all'account (o la noreply che ti dà il sito).
Ho committato sul ramo sbagliato
Se il commit è solo locale e l'ultimo:
git switch ramo-giusto
git cherry-pick HASH
git switch ramo-sbagliato
git reset --hard HEAD~1
reset --hard butta le modifiche non committate su quel ramo. Usalo solo se status è pulito e l'hash è quello giusto. Se il commit è già sul remote, non resettare: è un altro discorso, e spesso serve una mano.
Il merge è un disastro
git merge --abort
Torni allo stato prima del merge. Poi decidi: unisci di nuovo con calma, oppure chiedi a chi ha scritto l'altro ramo.
Quasi tutti i "Git è rotto" sono: ramo sbagliato, pull mancante, o file committati per sbaglio. Controlla status, log e remote. In quest'ordine.
Conclusione
Git è piccolo, se lo usi per quello che è. Cloni una volta. Guardi status. Aggiungi quello che deve stare nel commit. Scrivi un messaggio che tra un mese ha senso. Unisci i rami con merge. Aggiorni con pull, pubblichi con push. Ignori build e segreti. Non fai force push sul ramo degli altri.
GitHub e GitLab restano il posto dove sta origin. Non sono Git. Se l'autenticazione è una lotta, sistema le chiavi SSH e torna a lavorare. Come usiamo Git nei progetti è in tecnologie / Git; se serve un repository e un flusso di rilascio sul software aziendale, si parte da sviluppo software.
Risorse utili (autorevoli):
- Documentazione ufficiale Git - Manuale e reference dei comandi
- Pro Git (libro) - Libro ufficiale, anche in italiano
- git-scm.com - Download e documentazione
Approfondimenti
- Sviluppo software — servizio
- Docker per principianti: il primo container senza paura — articolo
- Chiavi SSH: crearne una e usarla senza farsi chiudere fuori — articolo
- Generatore di slug — strumento
- Git — tecnologia
Parliamone
Questo articolo riguarda la tua azienda?
Se uno dei problemi descritti riguarda anche i tuoi sistemi, possiamo valutare insieme la situazione. Il primo confronto è gratuito.