Introduzione
git push carica commit a un remote e aggiorna i ref di quel remote. A differenza del fetch, modifica lo stato sul server, quindi esistono meccanismi di sicurezza per prevenire la sovrascrittura del lavoro di altre persone.
La sequenza
- Risolve l'URL del remote e il refspec target.
- Apre una connessione.
- Negozia capabilities.
- Il server pubblicizza i valori correnti dei ref.
- Il client controlla ogni push: è un fast-forward del ref del server?
- Il client impacchetta gli oggetti mancanti e li carica.
- Il server esegue l'hook
pre-receive. - Per ogni ref, il server esegue l'hook
updatee aggiorna atomicamente il ref. - Il server esegue l'hook
post-receive. - Il server riporta successo o rifiuto al client.
Comandi
git push # branch corrente all'upstream
git push origin main # esplicito
git push -u origin feature/login # imposta upstream
git push origin --delete feature/login # cancella branch remoto
git push origin v1.0.0 # pusha un tag
git push --follow-tags
git push --force-with-lease
Enforcement del fast-forward
Per default, un push viene rifiutato se non sarebbe un fast-forward del ref remoto. Questo protegge dal sovrascrivere accidentalmente lavoro che altri hanno pushato:
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the tip of your current branch is behind ...
Risolvi facendo fetch e integrando, poi pushando di nuovo.
Force push
git push --force # pericoloso: ignora lo stato remoto
git push --force-with-lease # più sicuro: rifiuta se il remote si è mosso
git push --force-with-lease=feature/login:abc1234
--force-with-lease richiede che il ref remoto sia ancora uguale a ciò che dice il tuo ref di tracking. Preferiscilo sempre.
Push atomici
git push --atomic origin branchA branchB
Con --atomic, o tutti gli aggiornamenti riescono o nessuno; utile quando i ref devono muoversi insieme.
Politiche di push
git config --global push.default simple # branch corrente al suo upstream
git config --global push.default current # branch corrente al remote con stesso nome
git config --global push.default upstream # corrente al nome del suo upstream
git config --global push.autoSetupRemote true # 2.37+: auto -u per nuovi branch
Hook lato server
Le piattaforme di hosting eseguono hook pre-receive e update per applicare politiche (commit firmati, naming dei branch, CI verde obbligatoria). Quando un push viene rifiutato, il messaggio del server nomina il ref o commit incriminato. Leggi il messaggio prima di riprovare.
Errori comuni
Force-pushare a un branch condiviso come main e riscrivere i commit di altri. Coordinati, o usa --force-with-lease solo su branch privati. Pushare i tag individualmente e dimenticare di pushare i commit, lasciando tag dangling sul server. Usa --follow-tags. Pushare a un remote sbagliato perché ne hai più configurati; git push -v mostra esattamente dove sta andando. Infine, aspettarsi che git push --delete cancelli file; cancella ref. Per cancellare file, committa una rimozione e pusha quel commit.