Introduction
git push téléverse les commits vers un remote et met à jour les refs de ce remote. Contrairement à fetch, il modifie l'état du serveur, donc des mécanismes de sécurité existent pour empêcher d'écraser le travail des autres.
La séquence
- Résoudre l'URL du remote et le refspec cible.
- Ouvrir une connexion.
- Négocier les capacités.
- Le serveur annonce les valeurs courantes des refs.
- Le client vérifie chaque push : est-ce un fast-forward de la ref du serveur ?
- Le client packe les objets manquants et les téléverse.
- Le serveur exécute le hook
pre-receive. - Pour chaque ref, le serveur exécute le hook
updateet met à jour la ref atomiquement. - Le serveur exécute le hook
post-receive. - Le serveur signale succès ou rejet au client.
Commandes
git push # branche courante vers upstream
git push origin main # explicite
git push -u origin feature/login # définit l'upstream
git push origin --delete feature/login # supprime la branche distante
git push origin v1.0.0 # pousse un tag
git push --follow-tags
git push --force-with-lease
Application du fast-forward
Par défaut, un push est rejeté s'il ne ferait pas un fast-forward de la ref distante. Cela protège contre l'écrasement accidentel du travail poussé par d'autres :
! [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 ...
Résolvez en fetchant et intégrant, puis poussez à nouveau.
Push forcé
git push --force # dangereux : ignore l'état distant
git push --force-with-lease # plus sûr : refuse si le distant a bougé
git push --force-with-lease=feature/login:abc1234
--force-with-lease exige que la ref distante égale toujours ce que dit votre ref de tracking. Préférez-le toujours.
Pushes atomiques
git push --atomic origin branchA branchB
Avec --atomic, soit toutes les mises à jour réussissent, soit aucune ; utile quand les refs doivent bouger ensemble.
Politiques de push
git config --global push.default simple # branche courante vers son upstream
git config --global push.default current # branche courante vers le remote du même nom
git config --global push.default upstream # courante vers le nom de son upstream
git config --global push.autoSetupRemote true # 2.37+ : -u auto pour nouvelles branches
Hooks côté serveur
Les plateformes d'hébergement exécutent des hooks pre-receive et update pour appliquer des politiques (commits signés, nommage de branches, CI verte obligatoire). Quand un push est rejeté, le message du serveur nomme la ref ou le commit fautif. Lisez le message avant de réessayer.
Erreurs fréquentes
Force-pusher vers une branche partagée comme main et réécrire les commits des autres. Coordonnez, ou utilisez --force-with-lease uniquement sur des branches privées. Pusher des tags individuellement et oublier de pousser des commits, laissant des tags pendants sur le serveur. Utilisez --follow-tags. Pusher vers un mauvais remote parce que vous en avez plusieurs configurés ; git push -v affiche exactement où il va. Enfin, attendre que git push --delete supprime des fichiers ; il supprime des refs. Pour supprimer des fichiers, commitez une suppression et poussez ce commit.