Pull request in Git: cos'è e come creare una PR su GitHub
La pull request (PR) è una richiesta di unire il vostro branch nel branch principale del repository su GitHub: mostrate le modifiche, i colleghi le discutono e le verificano, e dopo l'approvazione il branch viene unito. In GitLab la stessa funzione si chiama merge request (MR). È una funzione della piattaforma, non un comando Git, e non ha nulla a che vedere con il comando git pull.
La pull request (PR) è una proposta di integrare le modifiche da un branch in un altro, presentata su una piattaforma come GitHub. Inviate il branch al server, aprite la PR, e il team vede il diff, commenta le righe, avvia i controlli automatici e solo dopo preme il pulsante di merge. Su GitLab lo stesso meccanismo si chiama merge request (MR). In breve, alla domanda «cos'è una pull request in git» la risposta è: è il punto di controllo tra «ho scritto il codice» e «il codice è entrato nel main».
Pull request in Git: cos'è e da dove viene il nome
Il nome si è affermato per ragioni storiche. Chi ha realizzato le modifiche chiede al proprietario del repository di «tirare» (pull) il suo branch. Su GitLab si è preferito chiamarla per il risultato: merge request, richiesta di unione. Bitbucket e Azure DevOps usano la dicitura «pull request». Il concetto è lo stesso: un branch sorgente, un branch di destinazione, una descrizione, la discussione, i controlli e il pulsante di merge.
È importante capire che la pull request non fa parte di Git. In Git non esiste un oggetto «PR»: non si può creare con un commit né trovare nella cartella .git. È un'entità della piattaforma: GitHub conserva la descrizione, i commenti e lo stato dei controlli, mentre Git si occupa solo dei branch e dei commit che fanno parte della PR.
Nel gergo degli sviluppatori la sigla PR indica quasi sempre la pull request: «ti mando la PR», «PR in revisione», «ho unito la PR». Per GitLab si dice MR.
Pull request e git pull: qual è la differenza
Le due cose vengono confuse di continuo a causa di nomi simili. Il comando git pull scarica i nuovi commit dal repository remoto e li integra subito nel branch corrente: è un'operazione locale nel terminale. La pull request, invece, è una pagina web su GitHub con la proposta di unire un branch in un altro.
| git pull | Pull request | |
|---|---|---|
| Dove si trova | Comando Git nel terminale | Pagina su GitHub, GitLab, Bitbucket |
| Cosa fa | Porta a voi le modifiche dal server | Propone di unire il vostro branch in un altro condiviso |
| Chi partecipa | Solo voi | Autore, revisori, CI |
| Serve la piattaforma? | No, basta il remote | Sì |
Non esiste un comando «git pull request» in Git. C'è un vecchio strumento, git request-pull, che però genera solo il testo di un'e-mail di riepilogo delle modifiche per la distribuzione e non ha nulla a che fare con le PR su GitHub.
Perché servono le pull request
Finché un progetto lo segue una sola persona, si può committare direttamente nel main. Quando nel repository lavorano in due o più, i push diretti nel branch principale diventano la causa di build rotte e di lavoro perso. La pull request risolve più problemi insieme:
- revisione del codice — un secondo sviluppatore vede le modifiche prima che entrino nel main e trova gli errori sfuggiti all'autore;
- controlli automatici — GitHub Actions o un altro CI esegue test e linter a ogni PR, e uno stato rosso impedisce di unire codice che non funziona;
- storia delle decisioni — dopo un anno, dalla PR si capisce non solo cosa è stato cambiato, ma anche perché, con la discussione;
- contributi a progetti altrui — nei progetti open source non avete i diritti di scrittura, e la PR da un fork è l'unico modo per proporre una correzione;
- protezione dei branch — le regole di protezione di GitHub possono vietare il push diretto nel main e richiedere una PR approvata.
Come creare una pull request su GitHub da un branch
È lo scenario principale per un team in cui tutti hanno i diritti di scrittura sul repository. Il lavoro avviene in un branch di funzionalità, e il main cambia solo tramite PR.
Passo 1. Creare un branch dal main aggiornato
git switch main
git pull
git switch -c feature/login-form
Il nome del branch conviene sceglierlo in modo chiaro: feature/…, fix/…, numero del task. Il revisore capisce subito di cosa si parla.
Passo 2. Fare i commit
git add src/login.js
git commit -m "Aggiungi il modulo di accesso"
Una PR per ogni attività. Una PR piccola, di 100–300 righe, si controlla in fretta e con attenzione; una da 3000 righe viene approvata quasi senza leggerla.
Passo 3. Inviare il branch al server (git push per la pull request)
git push -u origin feature/login-form
Il flag -u collega il branch locale a quello remoto, e in seguito basta git push. La risposta di GitHub include già il link per creare la PR:
remote: Create a pull request for 'feature/login-form' on GitHub by visiting:
remote: https://github.com/team/app/pull/new/feature/login-form
Passo 4. Aprire la PR nell'interfaccia web
Aprite il link del terminale oppure il repository su GitHub: dopo un push recente compare un banner con il pulsante «Compare & pull request». Un'altra strada è la scheda «Pull requests» con il pulsante «New pull request».
- Controllate la coppia di branch: base è dove si unisce (di solito
main), compare è il vostro branch. - Scrivete il titolo: che cosa è stato fatto, all'imperativo o con una breve descrizione.
- Nella descrizione spiegate il perché, come verificare e cosa resta fuori dal lavoro. Se il repository ha un modello di PR, i campi si compilano da soli.
- A destra assegnate i revisori (Reviewers), l'assegnatario e le etichette, se il team le usa.
- Premete «Create pull request» oppure scegliete la bozza (ne parliamo più avanti).
Creare una PR dal terminale: GitHub CLI
Se non volete passare al browser, c'è l'utilità ufficiale gh. Non è un comando di Git ma un programma di GitHub, ed è comoda per le PR:
gh pr create --base main --title "Aggiungi il modulo di accesso" --body "Closes #42"
gh pr list
gh pr checkout 57
gh pr merge 57 --squash
Alla domanda «quali sono i comandi git per la pull request» la risposta onesta è questa: Git gestisce branch, commit e push, mentre la PR si crea sulla piattaforma, nel browser, con gh o tramite API.
Come fare una pull request a un repository altrui tramite fork
Nei progetti open source non avete i diritti di scrittura. Quindi prima fate un fork, cioè una vostra copia del repository su GitHub, lavorate lì e proponete le modifiche al progetto originale.
- Nella pagina del progetto premete «Fork»: otterrete
github.com/you/project. - Clonate il vostro fork e aggiungete l'originale come secondo remote, di solito chiamato
upstream. - Create un branch, fate i commit e inviate il branch al vostro fork.
- Su GitHub aprite la PR: base repository è il progetto originale, head repository è il vostro fork con il vostro branch.
git clone git@github.com:you/project.git
cd project
git remote add upstream https://github.com/owner/project.git
git switch -c fix/typo-readme
git commit -am "Correggi un refuso nel README"
git push -u origin fix/typo-readme
Prima di lavorare date un'occhiata al file CONTRIBUTING.md: di solito descrive le regole per i commit, i test e se bisogna prima aprire una issue. Tenete il fork aggiornato con git fetch upstream e git rebase upstream/main nel vostro branch, così la PR non resta indietro rispetto all'originale.
Merge request in GitLab: cos'è e come crearla
La merge request di GitLab è l'equivalente completo della pull request. Cambiano i nomi e alcuni dettagli dell'interfaccia, ma il processo è lo stesso: branch, push, richiesta di unione, revisione, merge.
Si può creare una MR in diversi modi:
- tramite il link che GitLab stampa nel terminale dopo il
git pushdi un nuovo branch; - nella sezione Merge requests del progetto, con il pulsante «New merge request», scegliendo il branch sorgente e quello di destinazione;
- direttamente durante il push, con le push option di GitLab, senza aprire il browser.
git push -o merge_request.create -o merge_request.target=main origin feature/login-form
La terminologia di GitLab è leggermente diversa: l'approvazione si chiama approve, il responsabile dell'unione è l'assignee, e al posto di GitHub Actions lavora GitLab CI/CD con il file .gitlab-ci.yml. Esistono anche le bozze di MR, chiamate Draft.
Revisione della pull request
Il revisore apre la scheda «Files changed» e vede il diff. Su qualsiasi riga può lasciare un commento oppure proporre una correzione pronta (suggestion) che l'autore applica con un clic. I commenti si raccolgono in una revisione e si inviano insieme con uno dei tre esiti:
- Comment — solo osservazioni, senza decisione;
- Approve — le modifiche sono approvate;
- Request changes — servono altre modifiche, il merge non è consigliato.
Una buona revisione guarda la logica, la leggibilità, i test e i casi limite, e non discute sui gusti: la formattazione è meglio affidarla a un linter nel CI. L'autore dovrebbe rispondere a ogni commento: ho corretto, ne abbiamo discusso, lo lasciamo così con una spiegazione.
Come verificare localmente una PR altrui (git checkout della pull request)
A volte il codice va eseguito sul proprio computer. Se il branch si trova nello stesso repository, bastano git fetch e git switch. Per le PR da un fork GitHub mette a disposizione riferimenti speciali pull/<numero>/head:
git fetch origin pull/57/head:pr-57
git switch pr-57
In GitLab i riferimenti analoghi si chiamano merge-requests/<numero>/head. Oppure si usa semplicemente gh pr checkout 57, se è installato GitHub CLI.
Come aggiornare la pull request dopo le osservazioni
La PR è collegata al branch, non a singoli commit. Basta fare nuovi commit nello stesso branch e inviarli: la PR si aggiorna da sola, senza crearne una nuova.
git commit -am "Applica le osservazioni della revisione"
git push
Git rebase della pull request: aggiornare il main
Mentre la PR è in revisione, il main va avanti. Se GitHub segnala che il branch è indietro o che ci sono conflitti, aggiornatelo. Con il rebase la cronologia resta lineare:
git fetch origin
git rebase origin/main
# risolvere i conflitti, git add, git rebase --continue
git push --force-with-lease
Dopo un rebase gli hash dei commit cambiano, quindi un push normale viene rifiutato e serve quello forzato. Usate --force-with-lease: si rifiuta di sovrascrivere il branch se nel frattempo sono arrivati commit altrui. Se nel branch lavorate in più persone, è più sicuro integrare il main con git merge origin/main, senza riscrivere la cronologia.
Come unire una pull request: merge, squash e rebase
Quando la revisione è approvata e i controlli sono verdi, la PR può essere unita. GitHub offre tre modalità, e l'amministratore del repository può lasciarne attive solo alcune.
| Modalità | Risultato nel main | Quando è adatta |
|---|---|---|
| Create a merge commit | Tutti i commit del branch più un commit di merge | Serve la cronologia completa e si vede quali commit sono arrivati insieme |
| Squash and merge | Un solo commit con tutte le modifiche della PR | Nel branch ci sono molti piccoli «fix typo» e conta un log del main pulito |
| Rebase and merge | I commit del branch uno per uno, senza commit di merge | I commit sono ordinati e ognuno ha senso da solo |
Il merge della pull request dall'interfaccia è in sostanza lo stesso git merge, eseguito però sul server. Dopo l'unione GitHub propone di eliminare il branch: accettate, non serve più. In locale poi pulite:
git switch main
git pull
git branch -d feature/login-form
Si può unire la PR anche a mano dal terminale: unite il branch nel main in locale e fate il push. GitHub riconosce che i commit del branch sono entrati nella base e marca la PR come unita. Però così si perdono i controlli e le regole di protezione del branch, ed è per questo che nei team di solito si unisce con il pulsante.
Auto-merge e merge queue
Se i controlli sono lenti, si può attivare l'unione automatica: la PR viene unita da sola quando tutte le condizioni sono soddisfatte. Nei repository grandi si usa la coda di merge (merge queue), che verifica ogni PR sopra quelle già in coda, così il main non si rompe per modifiche incompatibili tra loro.
Bozze di pull request (Draft)
La bozza è una PR non ancora pronta per la revisione. Non può essere unita, e i revisori non ricevono una richiesta di verifica. Le bozze sono utili per mostrare presto la direzione, avviare il CI o raccogliere pareri sull'architettura. Su GitHub, al momento della creazione, scegliete la versione bozza dal menu a discesa del pulsante oppure usate gh pr create --draft. Quando il lavoro è pronto, premete «Ready for review». In GitLab la bozza è indicata dal prefisso Draft: nel titolo della MR.
Collegare la pull request alle issue
Se nella descrizione della PR scrivete una parola chiave seguita dal numero dell'attività, dopo l'unione nel branch predefinito GitHub chiude automaticamente la issue:
Closes #42
Fixes #17
Resolves #8
Funzionano le parole close, fix e resolve nelle loro forme (closes, fixed, resolves). Il semplice riferimento #42 senza parola chiave crea un collegamento, ma non chiude l'attività. In GitLab funzionano allo stesso modo Closes #42 e le frasi simili.
Si può eliminare una pull request o una merge request?
Un normale partecipante non può eliminare una PR su GitHub: può solo chiuderla con il pulsante «Close pull request». La PR chiusa resta nella cronologia e può essere riaperta. Il branch va eliminato a parte. Eliminare definitivamente una PR è possibile solo tramite il supporto GitHub, per esempio se vi sono finiti dei segreti.
In GitLab la MR può essere chiusa dall'autore o da un partecipante con i permessi adeguati, mentre l'eliminazione spetta al proprietario del progetto o all'amministratore. Se in una PR è finita una password o un token, chiuderla non basta: revocate subito il segreto, perché i commit erano già sul server.
Errori tipici con la pull request
- PR dal main. Avete committato nel vostro main e aperto la PR da lì. La PR successiva conterrà anche le vecchie modifiche. Lavorate sempre in un branch separato.
- Branch base sbagliato. La PR è stata aperta su
developinvece che sumain, o viceversa. La base si cambia con il pulsante Edit accanto al titolo della PR. - Nel diff sono finiti file inutili. Build,
node_modules,.env. Aggiungeteli a.gitignoree toglieteli dall'indice congit rm --cached. - PR enorme. Dividete il lavoro in più PR consecutive.
- Push normale dopo un rebase. Errore
rejected (non-fast-forward). Servegit push --force-with-lease, non--force. - Conflitti. Non risolveteli alla cieca nell'editor web: aggiornate il main in locale, risolvete e verificate i test.
Pull request nel git flow e in altri processi
La pull request si adatta a qualsiasi processo di team. In GitHub Flow è semplice: branch dal main, PR, revisione, merge, deploy. Nel git flow le PR si aprono verso develop dai branch di funzionalità, mentre i branch di release e hotfix passano anch'essi tramite PR verso main. Nello sviluppo trunk-based le PR sono brevi e vivono ore, non giorni. Qualunque sia il processo, la regola è una sola: le modifiche ai branch condivisi passano solo tramite pull request.
Conclusioni
La pull request è un meccanismo della piattaforma, non un comando di Git: un branch inviato al server, più una pagina con discussione, revisione e controlli. In GitLab si chiama merge request; nel linguaggio comune si dice PR e MR. Create la PR da un branch separato, tenetela piccola, aggiornatela con il push nello stesso branch e scegliete la modalità di merge in base alla storia del progetto. Fork, branch di funzionalità e pull request sono trattati nella pratica nel corso su Git.
Domande frequenti
Quanti revisori servono per una pull request?
Di solito bastano uno o due. Il numero minimo di approvazioni si imposta nelle regole di protezione del branch, e senza di esse il pulsante di merge non è disponibile.
Posso creare una pull request senza fare un fork?
Sì, se avete i diritti di scrittura sul repository: create un branch nel repository stesso e aprite la PR da lì. Il fork serve solo quando non avete i diritti di scrittura.
Cosa faccio se nessuno guarda la mia PR da molto tempo?
Ricordate gentilmente al revisore con un commento o in una chat del team. Nei progetti open source l'attesa può durare settimane: verificate anche che la PR rispetti le regole di CONTRIBUTING.md.
Posso aprire una pull request tra due branch del mio fork?
Sì, nella pagina di confronto scegliete il vostro fork sia come base sia come head. È utile per rivedere le proprie modifiche prima di inviarle al progetto originale.
Perché nella PR compaiono commit che non ho fatto io?
Probabilmente il branch non è stato creato dal main aggiornato, oppure è stato scelto il branch base sbagliato. Fate un rebase sul main aggiornato o cambiate la base nelle impostazioni della PR.
Questo argomento è trattato in modo approfondito, con pratica, nel corso «Git da zero a sviluppatore sicuro».
- Lavoro di squadra: fork, feature branch e pull request
- Processi Git nei team reali: quale workflow scegliere