git push
Mettre à jour les références distantes avec les objets associés
La commande 'git push' envoie le contenu du dépôt local vers un dépôt distant. Elle transfère les commits et les mises à jour de branches (et les tags, quand vous les demandez avec --tags ou --follow-tags) de votre dépôt local vers un dépôt distant, pour que vos modifications soient disponibles pour les autres. Push est la façon de partager votre travail : après avoir committé en local, vous poussez pour vous synchroniser avec l’équipe. Par défaut (push.default=simple), git push ne met à jour que la branche upstream de la branche courante, qui doit exister et porter le même nom, et seulement s’il s’agit d’un fast-forward (la branche distante est un ancêtre de votre branche locale).
Synopsis
git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [-f | --force] [-d | --delete] [--prune] [-q | --quiet] [-v | --verbose] [-u | --set-upstream] [-o <string>] [--force-with-lease[=<refname>[:<expect>]] [--force-if-includes]] [--no-verify] [<repository> [<refspec>...]]Options
Choisir la bonne option
L’échelle de sécurité du force push
Quand vous devez écraser l’historique distant, choisissez l’option la plus sûre qui convient à votre situation
| Commande | Niveau de risque | Vérifie le distant | Quand il échoue | Cas d’usage |
|---|---|---|---|---|
git push | Sans risque | ✓ Fast-forward seulement | Si le distant a de nouveaux commits | Travail quotidien normal |
git push --force-with-lease --force-if-includes | Forçage le plus sûr | ✓ Pointe distante dans l’historique local | Si vous n’avez pas intégré les modifications distantes | Après un rebase quand d’autres ont pu pousser |
git push --force-with-lease | Forçage plus sûr | ✓ Distant inchangé depuis le fetch | Si le distant a changé depuis le dernier fetch | Après un rebase sur une branche personnelle |
git push --force | Dangereux | ✗ Écrase à l’aveugle | Jamais (sauf refus du serveur) | Seulement quand vous êtes certain, ou seul sur la branche |
Ce qui est poussé
Contrôler l’étendue de ce que vous envoyez au dépôt distant
| Commande | Pousse | Tags inclus | Usage typique |
|---|---|---|---|
git push origin main | Une seule branche | ✗ | Pousser une branche précise |
git push -u origin branch | Une branche + configure le suivi | ✗ | Premier push d’une nouvelle branche |
git push --all | Toutes les branches | ✗ | Synchroniser toutes les branches locales |
git push --tags | Tags seulement (pas de branches) | ✓ Tous les tags | Pousser les tags de version |
git push --follow-tags | Branche courante | ✓ Seulement les annotés accessibles | Pousser avec les tags de release correspondants |
git push --mirror | Tout | ✓ Tout | Clone exact vers le distant (supprime les références qui n’existent qu’à distance) |
Sortie et retours
Adapter la verbosité et le format de sortie à vos besoins
| Commande | Niveau de sortie | Affiche la progression | Lisible par une machine | Idéal pour |
|---|---|---|---|---|
git push | Standard | Dans le terminal seulement | ✗ | Usage interactif normal |
git push --verbose | Détaillé | ✓ | ✗ | Déboguer un push |
git push --quiet | Erreurs seulement | ✗ | ✗ | Scripts, pipelines de CI |
git push --progress | Standard + progression forcée | ✓ Toujours | ✗ | Scripts qui ont besoin de la progression dans les logs |
git push --porcelain | Structuré | ✗ | ✓ Séparé par des tabulations | Analyser les résultats du push dans des scripts |
Sécurité et vérification
Vérifications avant push et options de contrôle
| Commande | Lance les hooks | Vérifie | Crée un commit | Quand l’utiliser |
|---|---|---|---|---|
git push | ✓ pre-push | Le distant accepte | N/A | Workflow normal |
git push --dry-run | ✓ pre-push | Ce qui se passerait | ✗ Aperçu seulement | Avant les pushes importants |
git push --atomic | ✓ | Toutes les références ou aucune | Tout ou rien | Pousser plusieurs branches ensemble |
git push --no-verify | ✗ Saute le pre-push local (les hooks du serveur tournent toujours) | Le distant accepte | N/A | Urgence quand les hooks vous bloquent |
git push --signed | ✓ | Signature GPG | Signé de façon cryptographique | Dépôts très sécurisés, prouver son identité |
Gestion des dépôts distants et des branches
Options pour gérer les références distantes et les relations entre branches
| Commande | Action | Touche le distant | Cas d’usage |
|---|---|---|---|
git push -u origin branch | Push + définir l’upstream | Ajoute une branche | Premier push, configure le suivi |
git push origin --delete branch | Supprimer une branche distante | Retire une branche | Nettoyer les branches fusionnées |
git push --prune | Supprimer les branches distantes que vous avez supprimées en local (nécessite --all ou un refspec à joker) | Retire des branches | Répercuter les suppressions sur le distant |
git push --repo=<url> | Pousser vers un dépôt distant précis | Dépôt distant cible | Pousser vers une autre URL distante |
Exemples de workflows
git remote add origin https://github.com/user/repo.gitAjouter l’URL du dépôt distant
git push -u origin mainPousser la branche main et lui faire suivre origin/main
git statusVérifier que vous êtes sur la bonne branche et avez des commits à pousser
git pushPousser vers la branche upstream suivie
git checkout featurePasser sur votre branche de fonctionnalité
git rebase mainRebaser sur main (réécrit l’historique des commits)
git push --force-with-leaseForcer le push sans risque - échoue si quelqu’un d’autre a poussé
git checkout -b feature/new-loginCréer la nouvelle branche et y basculer
git add . && git commit -m "Add new login"Faire vos modifications et committer
git push -u origin feature/new-loginPousser et configurer le suivi de l’upstream
git push origin --delete feature/old-branchSupprimer la branche distante
git branch -d feature/old-branchSupprimer aussi la branche locale
git push --all originPousser toutes les branches de refs/heads/
git push --tags originPousser aussi tous les tags, si vous le souhaitez
Dépannage
! [rejected] main -> main (fetch first) / (non-fast-forward)
Cause : La branche distante a des commits que votre branche locale n’a pas. Quelqu’un d’autre a poussé des modifications, ou vous avez fait un rebase/amend de commits déjà poussés.
Récupérez d’abord les modifications distantes avec 'git pull --rebase' ou 'git pull --no-rebase', résolvez les conflits éventuels, puis poussez de nouveau. Ne forcez (de préférence avec '--force-with-lease') que si vous êtes certain que personne d’autre n’utilise la branche.
git pull --rebase && git pushgit@github.com: Permission denied (publickey)
Cause : L’authentification SSH a échoué : aucune clé n’est chargée, ou votre clé publique n’est pas ajoutée à votre compte. (Un manque de droit d’écriture donne une autre erreur, « Permission to ... denied ».)
Vérifiez que votre clé SSH est ajoutée à votre compte GitHub/GitLab. Testez avec 'ssh -T git@github.com'. En HTTPS, vérifiez que vous utilisez les bons identifiants.
ssh -T git@github.comfatal: No configured push destination
Cause : Le dépôt n’a aucun dépôt distant configuré. (Si un dépôt distant existe mais que la branche n’a pas d’upstream, vous obtenez plutôt « The current branch ... has no upstream branch ».)
Ajoutez un dépôt distant avec 'git remote add origin <url>', puis poussez en définissant l’upstream avec 'git push -u origin <branch>'.
git push -u origin mainYour branch is behind 'origin/main'
Cause : La branche distante a des commits plus récents que votre branche locale. Vous devez intégrer ces modifications avant de pousser.
Récupérez les modifications distantes et fusionnez-les ou rebasez-les dans votre branche locale avant de pousser.
git pull origin main && git pushrefusing to update checked out branch
Cause : Vous essayez de pousser vers un dépôt non-bare où cette branche est actuellement extraite. Cela pourrait rendre son répertoire de travail incohérent.
Poussez vers un dépôt bare, ou demandez au destinataire d’extraire d’abord une autre branche. Cela arrive en général avec des serveurs personnels, pas avec GitHub/GitLab.
git config receive.denyCurrentBranch updateInsteaderror: failed to push some refs to '<remote-url>'
Cause : Erreur générique aux causes multiples : mises à jour non-fast-forward, échecs de hooks ou problèmes de permissions. Lisez le message d’erreur détaillé au-dessus de cette ligne.
Lisez toute la sortie d’erreur. En général c’est un problème de non-fast-forward (faites d’abord un pull) ou un échec du hook pre-push (corrigez ce que le hook signale).
git pull --rebase && git pushLe hook pre-push a échoué
Cause : Un hook pre-push (tests, lint, etc.) a trouvé des problèmes et a bloqué le push.
Corrigez les problèmes signalés par le hook. Ne le contournez avec '--no-verify' qu’en cas de nécessité absolue et en connaissance de cause.
git push --no-verifyremote: Repository not found
Cause : L’URL du dépôt est incorrecte, le dépôt a été supprimé ou renommé, ou vous n’y avez pas accès.
Vérifiez l’URL du dépôt avec 'git remote -v'. Assurez-vous que le dépôt existe et que vous y avez accès. Mettez l’URL à jour si besoin.
git remote set-url origin https://github.com/user/correct-repo.gitAstuces et pièges
Bonnes pratiques
- ✓Faites toujours un pull avant de pousser : lancez 'git pull' (ou 'git fetch' suivi d’un merge ou d’un rebase) avant de pousser, pour avoir les dernières modifications distantes et éviter les pushes rejetés.
- ✓Utilisez --force-with-lease plutôt que --force : si vous devez forcer, --force-with-lease est plus sûr car il échoue si quelqu’un d’autre a poussé depuis votre dernier fetch (ajoutez --force-if-includes pour plus de sécurité).
- ✓Définissez l’upstream au premier push : utilisez 'git push -u origin branch-name' pour une nouvelle branche afin de configurer le suivi. Ensuite, un simple 'git push' suffit.
- ✓Ne forcez jamais un push sur des branches partagées : forcer sur main, master ou develop peut détruire le travail des autres. Utilisez des commits de revert plutôt que de réécrire l’historique.
- ✓Utilisez des règles de protection de branches : configurez votre dépôt pour interdire les force pushes sur les branches importantes et exiger des relectures de pull requests.
- ✓Poussez souvent pour sauvegarder votre travail : pousser régulièrement vos branches de fonctionnalité sert de sauvegarde et montre votre avancement aux autres.
- ✓Vérifiez avant de pousser : utilisez 'git push --dry-run' pour voir ce qui serait poussé sans rien pousser. Idéal pour revérifier.
- ✓Nettoyez les branches distantes : supprimez les branches de fonctionnalité fusionnées avec 'git push origin --delete branch-name' pour garder le dépôt distant en ordre.
- ✓Utilisez les pushes atomiques pour des modifications liées : quand vous poussez plusieurs branches qui dépendent les unes des autres, utilisez '--atomic' pour que tout réussisse ou que rien ne passe.
- ✓Signez les pushes importants : pour les dépôts critiques, utilisez '--signed' pour signer vos pushes avec GPG et permettre leur vérification (le serveur doit accepter les pushes signés, sinon le push échoue).
Erreurs fréquentes
- ✗Pousser sans avoir fait de pull : si le dépôt distant a de nouveaux commits, votre push sera rejeté. Faites toujours 'git pull' (ou fetch, puis merge/rebase) d’abord pour intégrer les modifications distantes.
- ✗Utiliser --force sur des branches partagées : forcer réécrit l’historique et peut détruire le travail des autres. Utilisez plutôt --force-with-lease, ou mieux, évitez complètement de forcer sur les branches partagées.
- ✗Oublier de définir l’upstream avec -u : au premier push d’une nouvelle branche, utilisez 'git push -u origin branch-name' pour configurer le suivi. Sinon, il faudra préciser le dépôt distant et la branche à chaque fois.
- ✗Pousser vers la mauvaise branche : vérifiez votre branche courante avec 'git branch' avant de pousser. Utilisez une syntaxe explicite comme 'git push origin feature:feature' pour être sûr.
- ✗Ne pas comprendre les pushes rejetés : les erreurs « non-fast-forward » signifient que le dépôt distant a des commits que vous n’avez pas en local. Faites un pull et un merge/rebase avant de pousser - ne forcez pas simplement.
FAQ
'git push' envoie vos commits locaux vers un dépôt distant pour que vos modifications soient disponibles pour les autres. 'git pull' télécharge les commits d’un dépôt distant et les fusionne dans votre branche locale. Push envoie des données ; pull en rapporte.
On ne peut pas vraiment « annuler » un push, puisque c’est de l’historique partagé. Pour revenir en arrière sans risque, utilisez 'git revert HEAD' pour créer un nouveau commit qui annule les modifications, puis poussez de nouveau. Évitez 'git reset' + force push sur des branches partagées : cela réécrit un historique que d’autres ont peut-être déjà récupéré.
L’option -u crée une relation de suivi entre votre branche locale et la branche distante. Après 'git push -u origin feature', vous pouvez simplement utiliser 'git push' et 'git pull' sans préciser le dépôt distant et la branche à chaque fois.
Le force push (--force) ne doit servir que sur des branches où vous êtes seul à contribuer, comme une branche de fonctionnalité personnelle après un rebase. Ne forcez jamais sur des branches partagées comme main ou develop. Si vous devez le faire, utilisez --force-with-lease par sécurité.
Utilisez la syntaxe refspec : 'git push origin local-branch:remote-branch'. Par exemple, 'git push origin feature:experiment' pousse votre branche locale 'feature' vers une branche distante nommée 'experiment'.
En général, parce que le dépôt distant a des commits que vous n’avez pas en local (non-fast-forward). Lancez 'git pull' pour récupérer et fusionner ces modifications, résolvez les conflits éventuels, puis poussez de nouveau. Ne forcez pas sauf si vous êtes certain que c’est sans danger.
Utilisez 'git push --all origin' pour pousser toutes les branches locales vers le dépôt distant. Les tags demandent une commande séparée, car '--all' et '--tags' ne peuvent pas être combinés : 'git push --tags origin'.
'--force' écrase aveuglément la branche distante, quel que soit son état. '--force-with-lease' n’écrase que si le distant n’a pas changé depuis votre dernier fetch - il échoue si quelqu’un d’autre a poussé, ce qui protège son travail. Attention : un fetch (même un fetch en arrière-plan d’un IDE) rafraîchit cette vérification, donc ajoutez --force-if-includes pour exiger aussi que vous ayez intégré ce que vous avez récupéré.
Utilisez 'git push origin --delete branch-name' ou la forme courte 'git push origin :branch-name'. Les deux retirent la branche du dépôt distant.
Un simple 'git push' ne fonctionne que si la branche courante a une branche upstream configurée. Pour les nouvelles branches, il faut d’abord 'git push -u origin branch-name'. Vérifiez les relations de suivi avec 'git branch -vv'.