Domande su Git al colloquio: 25 domande con risposte
Al colloquio su Git di solito si verificano la comprensione del modello dei dati (commit, indice, ramo, HEAD), la differenza tra merge e rebase, fetch e pull, reset e revert, la capacità di risolvere i conflitti e di recuperare i commit persi, oltre alla conoscenza dei workflow di team come GitHub Flow e Git Flow.
Su Git si viene interrogati quasi a ogni colloquio per sviluppatori, tester o DevOps: a volte con un blocco dedicato, a volte di sfuggita («come annullereste una release andata male?»). Chi intervista non cerca tanto la conoscenza dei flag, quanto la comprensione del modello: che cos'è un commit, dove punta un ramo, che cosa riscrive la cronologia. Qui trovate 25 domande tra le più frequenti, con risposte del livello che fa una buona impressione.
Le domande vanno dalle basi agli argomenti avanzati. Quando rispondete in un colloquio, se possibile portate un breve esempio tratto dalla pratica: viene apprezzato più della semplice ripetizione della documentazione.
Domande di base
1. Che cos'è Git e in cosa un sistema di controllo di versione distribuito si differenzia da uno centralizzato?
Git è un sistema di controllo di versione distribuito: conserva la cronologia delle modifiche di un progetto e permette a più persone di lavorarci in parallelo. Nei sistemi centralizzati (per esempio SVN) la cronologia completa sta su un unico server, mentre lo sviluppatore ha solo una copia di lavoro. In Git ogni clone contiene l'intera cronologia, quindi commit, rami, consultazione della storia e fusioni funzionano in locale e senza rete.
Ne derivano vantaggi pratici: alta velocità, lavoro offline, assenza di un punto unico di guasto. Un server come GitHub o GitLab, in Git, è semplicemente un accordo del team su quale copia considerare «principale», non una necessità tecnica.
2. Quali sono le tre aree con cui si lavora in Git?
La directory di lavoro (i file sul disco), l'indice o staging area (l'istantanea preparata del prossimo commit) e il repository locale (la cartella .git con la cronologia). git add sposta le modifiche dalla directory di lavoro all'indice, git commit dall'indice al repository.
Un dettaglio in più che fa bene citare è la quarta area, il repository remoto, con i comandi git push e git fetch che vi lavorano.
3. A cosa serve l'indice, se si potrebbe committare direttamente?
L'indice permette di costruire il commit in modo consapevole: tra dieci file modificati si possono committare solo i tre che riguardano un'attività, lasciando il resto. Con git add -p si possono scegliere anche singoli frammenti all'interno di un file.
È la base dei commit atomici: un commit, una modifica logica. Una cronologia così è facile da leggere, da revisionare, da annullare con revert e da trasferire con cherry-pick.
4. Che cos'è un commit dal punto di vista della struttura interna di Git?
Un commit è un oggetto che contiene il riferimento a un albero (tree) — l'istantanea di tutti i file del progetto — i riferimenti ai commit padre, l'autore, il committer, la data e il messaggio. È identificato da un hash SHA-1 (le versioni recenti hanno un supporto sperimentale per SHA-256) calcolato su tutto il contenuto.
Il concetto chiave: Git conserva istantanee, non differenze. I file invariati non vengono duplicati: l'albero punta semplicemente allo stesso blob. Poiché l'hash dipende dal padre, è impossibile modificare un commit vecchio senza cambiare gli hash di tutti quelli successivi.
5. Che cos'è un ramo e che cos'è HEAD?
Un ramo è soltanto un puntatore mobile a un commit: un file in .git/refs/heads/ che contiene un hash. Per questo creare un ramo in Git è istantaneo e non copia nulla. Quando fate un nuovo commit, il puntatore del ramo corrente avanza verso di esso.
HEAD è il puntatore alla posizione in cui vi trovate; di solito punta a un ramo (ref: refs/heads/main). Se vi spostate su un commit o un tag specifico, HEAD punta direttamente al commit: è lo stato di detached HEAD.
6. Che cos'è il detached HEAD e perché è pericoloso?
È la situazione in cui HEAD punta a un commit anziché a un ramo, per esempio dopo git switch --detach v1.0 o git checkout a1b2c3d. Si può guardare il codice e perfino committare, ma i nuovi commit non appartengono ad alcun ramo.
Se a quel punto passate a un altro ramo, quei commit diventano irraggiungibili e prima o poi vengono eliminati dal garbage collector. Per salvare il lavoro create un ramo: git switch -c fix-from-detached. Se ve ne siete già andati, l'hash si ritrova in git reflog.
7. In cosa si differenziano git fetch e git pull?
git fetch scarica i nuovi commit e aggiorna i rami di tracciamento remoto come origin/main, ma non tocca i vostri rami locali né i file. git pull è fetch più l'integrazione: di default un merge, con il flag --rebase o con l'impostazione pull.rebase=true un rebase.
I professionisti spesso eseguono il fetch separatamente, controllano con git log HEAD..origin/main e solo dopo decidono come integrare le modifiche.
8. Come funziona .gitignore e perché un file è ancora tracciato anche se lo avete inserito lì?
.gitignore definisce i modelli dei file che Git non deve proporre per l'aggiunta: dipendenze, build, log, configurazioni locali con segreti. Le regole valgono solo per i file non tracciati.
Se un file è già stato committato, il file .gitignore non ha effetto su di lui. Bisogna toglierlo dall'indice lasciandolo sul disco: git rm --cached config.local.php, poi committare la rimozione. Per capire quale regola si applica è utile git check-ignore -v percorso.
Rami, fusione e conflitti
9. Che cos'è un fast-forward merge?
Se il ramo di destinazione non è avanzato dal momento in cui è stato creato il ramo da unire, Git durante la fusione sposta semplicemente il suo puntatore sull'ultimo commit del ramo da integrare, senza creare un nuovo commit. La cronologia resta lineare.
Il flag --no-ff obbliga a creare un merge commit anche in questo caso: così nella cronologia si vede che un gruppo di commit costituiva una funzionalità separata. Il flag --ff-only, al contrario, accetta solo il fast-forward e rifiuta la fusione quando serve un vero merge.
10. Come nasce un conflitto di fusione e come si risolve?
Il conflitto si verifica quando in entrambi i rami sono state modificate le stesse righe di un file (o un file è stato eliminato in un ramo e modificato nell'altro) e Git non riesce a decidere automaticamente. Git interrompe la fusione e segna i punti di conflitto con i marcatori <<<<<<<, ======= e >>>>>>>.
git status # elenco dei file in conflitto
# correggete i file lasciando la versione giusta
git add app.js
git commit # per il merge; per il rebase — git rebase --continue
Una buona risposta include anche la prevenzione: rami piccoli, un pull frequente dal ramo principale, accordi sulla formattazione. E ricordate git merge --abort, se volete tornare indietro.
11. In cosa si differenziano merge e rebase?
merge unisce due rami creando un merge commit con due genitori; i commit esistenti non cambiano e la cronologia riflette onestamente il lavoro parallelo. rebase sposta i commit del vostro ramo sopra un altro ramo, creandone copie con nuovi hash; la cronologia risulta lineare.
La regola generale: il rebase serve a riordinare il proprio ramo locale prima della pubblicazione, il merge per integrare nei rami condivisi. Fare il rebase di commit pubblicati su cui lavorano altri porta a duplicati e confusione.
12. Che cos'è il rebase interattivo e a cosa serve?
git rebase -i HEAD~5 apre l'elenco degli ultimi cinque commit, dove per ciascuno potete scegliere un'azione: pick — tenere, reword — cambiare il messaggio, edit — fermarsi e correggere, squash e fixup — unire al precedente, drop — eliminare. Le righe si possono anche riordinare.
Lo scenario tipico: prima di una pull request trasformate «wip», «fix typo», «ancora un fix» in due o tre commit sensati. Una combinazione comoda è git commit --fixup=<hash> seguito da git rebase -i --autosquash.
13. Che cosa fa lo squash merge e quando lo si sceglie?
Con lo squash merge tutti i commit del ramo vengono compressi in un unico commit nel ramo di destinazione (git merge --squash oppure il pulsante su GitHub/GitLab). Il ramo principale riceve un commit per funzionalità.
Il vantaggio è una cronologia di main pulita. Lo svantaggio è che si perde il dettaglio interno della funzionalità, e Git non considera il ramo di partenza come già unito, quindi git branch -d si rifiuta di eliminarlo senza -D.
14. Che cos'è cherry-pick e quando è appropriato?
git cherry-pick <hash> applica le modifiche di un singolo commit al ramo corrente, creando un nuovo commit con lo stesso contenuto ma con un altro hash. Il caso classico è portare una correzione di bug da develop nel ramo di una release o di un hotfix.
Non va abusato: la stessa correzione vive in due commit diversi e le fusioni successive possono generare conflitti. Il flag -x aggiunge al messaggio un riferimento al commit originale.
Annullamento delle modifiche e ripristino
15. In cosa si differenziano git reset --soft, --mixed e --hard?
| Modalità | Puntatore del ramo | Indice | Directory di lavoro |
|---|---|---|---|
--soft | si sposta | non cambia | non cambia |
--mixed (predefinita) | si sposta | si azzera | non cambia |
--hard | si sposta | si azzera | si azzera, le modifiche vanno perse |
git reset --soft HEAD~3 è utile per rifare tre ultimi commit in uno solo. --hard è pericoloso per le modifiche non committate: non le recupera nemmeno il reflog.
16. In cosa si differenziano git revert e git reset?
reset sposta indietro il puntatore del ramo, riscrivendo di fatto la cronologia. revert crea un nuovo commit che annulla le modifiche del commit indicato e non riscrive nulla.
Per questo, per i commit già pubblicati in un ramo condiviso, la risposta corretta è revert: la cronologia dei colleghi non si rompe e l'annullamento è visibile nel log. Per un merge commit bisogna indicare il genitore principale: git revert -m 1 <hash>.
17. Come recuperare i commit dopo un git reset --hard per errore?
Con git reflog: registra localmente la storia degli spostamenti di HEAD e dei rami (di default le voci restano circa 90 giorni). Trovate la voce precedente al comando sbagliato e tornate lì:
git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~2
# 9f8e7d6 HEAD@{1}: commit: Aggiungere il pagamento
git reset --hard 9f8e7d6
Attenzione: il reflog salva solo ciò che è stato committato. Le modifiche che non sono mai finite in un commit (o almeno in uno stash) non si possono ripristinare con Git.
18. Come annullare le modifiche a un file e rimuoverlo dall'indice?
I comandi moderni sono git restore app.js (riporta il file allo stato dell'indice) e git restore --staged app.js (lo toglie dall'indice mantenendo le modifiche). In passato si usavano git checkout -- app.js e git reset HEAD app.js; funzionano ancora.
19. Che cos'è git stash e quali insidie ha?
git stash mette da parte temporaneamente le modifiche non committate e ripulisce la directory di lavoro — per esempio per passare subito a un hotfix. Si recuperano con git stash pop o apply.
Insidie: di default non vengono salvati i file non tracciati (serve -u); con pop può nascere un conflitto e in quel caso la voce non viene tolta dall'elenco; è facile dimenticarsi di uno stash. Per un lavoro lungo è meglio un commit in un ramo separato.
Domande avanzate e lavoro di team
20. Come si trova il commit che ha rotto una funzionalità?
Con git bisect, una ricerca binaria nella cronologia. Indicate un commit sicuramente errato e uno sicuramente corretto, e Git vi porta al centro dell'intervallo, fino a trovare il colpevole in log2(N) passi.
git bisect start
git bisect bad # la versione attuale è difettosa
git bisect good v2.3.0 # lì funzionava tutto
# verificate e rispondete good/bad finché Git non indica il commit
git bisect reset
Se avete uno script di verifica, il processo si automatizza: git bisect run npm test.
21. Perché git push --force è pericoloso e con cosa lo si sostituisce?
--force sovrascrive il ramo remoto con la vostra versione, e i commit che i colleghi hanno già inviato scompaiono dal server. È più sicuro git push --force-with-lease: sovrascrive il ramo solo se sul server si trova nello stato che avevate visto all'ultimo fetch.
Il push forzato è normale per il proprio ramo di funzionalità dopo un rebase; nel main e negli altri rami condivisi di solito viene vietato con la protezione dei rami sul server.
22. Quali workflow Git conoscete?
GitHub Flow: un ramo principale sempre pronto al deploy e rami di funzionalità brevi, che si integrano tramite pull request dopo la revisione e il CI. Git Flow: i rami main e develop, più feature/*, release/* e hotfix/*; è adatto ai prodotti con release versionate. Trunk-based development: tutti integrano nel trunk molto spesso, mentre il lavoro incompleto viene nascosto dietro feature flag.
Una risposta forte motiva la scelta: per un servizio web con deploy continuo il Git Flow di solito è eccessivo, mentre per una libreria con supporto di più versioni è giustificato.
23. Che cos'è una pull request e che cosa si controlla in essa?
La pull request (su GitLab si chiama merge request) è una richiesta di fusione di un ramo che passa la revisione del codice e i controlli automatici del CI prima di essere integrata. È una funzione della piattaforma (GitHub, GitLab, Bitbucket), non di Git stesso.
Una buona PR è piccola, risolve un solo problema, ha una descrizione chiara ed è collegata all'attività nel tracker. Il revisore guarda la correttezza, la leggibilità, i test e se nella PR sono finiti file superflui o segreti.
24. Quali regole seguite per scrivere un buon messaggio di commit?
Un titolo breve (fino a 50–72 caratteri) all'imperativo — «Aggiungere la validazione dell'e-mail» — poi una riga vuota e un corpo che spiega il «perché», non il «che cosa» (la modifica si vede nel diff). Molti team usano i Conventional Commits: feat:, fix:, docs:, refactor:.
Messaggi così permettono di generare il changelog, di trovare rapidamente ciò che serve con git log --grep e di capire le motivazioni delle modifiche anche a distanza di anni.
25. Che cosa fate se per errore avete caricato una password nel repository?
Prima di tutto revocate e rigenerate il segreto: è ormai compromesso, anche se lo eliminate dopo un minuto (cloni, fork, cache). Poi rimuovete il file dal tracciamento, inserite il percorso in .gitignore e, se necessario, ripulite la cronologia con strumenti come git filter-repo, seguiti da un force push e dall'avviso al team.
In questa domanda il selezionatore verifica le priorità: chi comincia riscrivendo la storia e dimentica la rotazione della chiave risponde in modo sbagliato.
Come prepararsi alle domande su Git
Il modo più affidabile non è memorizzare le risposte, ma eseguire ogni scenario a mano in un repository di prova: creare un conflitto e risolverlo, fare reset --hard e recuperare con il reflog, comprimere i commit con il rebase interattivo. Al colloquio su Git capita spesso un compito pratico o la richiesta di disegnare il grafo dei commit prima e dopo un comando — se l'avete già fatto da soli, la risposta viene naturale.
Utile anche un breve test su Git per l'autovalutazione: provate a rispondere senza suggerimenti a che cosa cambia nella cronologia dopo git rebase main o git revert HEAD. Se rispondete con sicurezza alla domanda «che cosa cambia nelle tre aree», le basi ci sono.
Riepilogo
Un colloquio su Git si riduce quasi sempre a tre temi: il modello dei dati (commit, rami, HEAD, indice), l'integrazione delle modifiche (merge, rebase, conflitti, fetch e pull) e l'annullamento sicuro (reset, revert, reflog). Aggiungete la comprensione del workflow di team e della pull request, e coprirete la gran parte delle domande. Tutti questi scenari, compreso il lavoro di team e gli strumenti avanzati, li esercitiamo in pratica nel corso di Git.
Domande frequenti
Quali domande su Git si fanno ai junior e quali ai senior?
Ai junior si chiedono add, commit, rami, conflitti, fetch e pull. Dagli sviluppatori esperti ci si aspetta la conoscenza di rebase, reflog, workflow, strategie di rilascio e la capacità di sistemare una cronologia compromessa in un team.
Al colloquio si danno compiti pratici su Git?
Spesso sì: chiedere di risolvere un conflitto, disegnare il grafo dopo un rebase o scegliere il comando giusto per annullare un commit già pubblicato. A volte fa parte di un compito di prova, in cui si valuta anche la cronologia dei commit.
Serve conoscere la struttura interna di Git?
Al livello di base sì: sapere che un commit conserva un'istantanea e il riferimento al padre, e che un ramo è un puntatore. I dettagli del formato degli oggetti e dei packfile vengono chiesti di rado.
I datori di lavoro guardano la cronologia dei commit del candidato?
Spesso guardano il profilo su GitHub o la cronologia del compito di prova. Messaggi sensati e commit atomici ordinati fanno una buona impressione.
Questo argomento è trattato in modo approfondito, con pratica, nel corso «Git da zero a sviluppatore sicuro».
- Perché serve Git — e perché senza non ti assumono
- Processi Git nei team reali: quale workflow scegliere
- Strumenti avanzati: rebase, stash, cherry-pick e tag