Votre git push affiche rejected et non-fast-forward ? C’est
le symptôme le plus courant en travail d’équipe : quelqu’un a poussé
des commits pendant que vous travailliez. Ce guide vous montre comment
débloquer la situation avec pull --rebase, quand utiliser
--force-with-lease, et comment diagnostiquer les divergences entre
votre branche locale et le remote.
Prérequis : Remotes fondamentaux et Branches distantes.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre pourquoi un push est rejeté (divergence de branches)
- Résoudre le rejet avec
pull --rebasepuis re-push propre - Utiliser
--force-with-leaseen toute sécurité quand nécessaire - Diagnostiquer les divergences entre local et remote
- Configurer
pull.rebasepour éviter les merges parasites automatiques
Comprendre le message d’erreur
Section intitulée « Comprendre le message d’erreur »Quand vous tentez un push et que le remote a avancé entre-temps :
! [rejected] main -> main (non-fast-forward)error: failed to push some refs to 'origin'hint: Updates were rejected because the tip of your current branchhint: is behind its remote counterpart.En clair : votre branche locale est en retard par rapport au remote. Git refuse de pusher parce que cela écraserait les commits de vos collègues.
Remote: A — B — C — D (commit de votre collègue)Local: A — B — C — E (votre commit)Le remote a D, vous avez E. Git ne peut pas simplement ajouter E après D car il remplacerait D.
Solution standard : git pull —rebase
Section intitulée « Solution standard : git pull —rebase »Dans 90% des cas, la solution est simple :
git pull --rebaseCette commande fait deux choses :
- Récupère les nouveaux commits du remote (
git fetch) - Rejoue vos commits locaux après les commits du remote
Résultat :
Avant: A — B — C — D (remote) \— E (local)
Après: A — B — C — D — E' (linéaire ✓)Votre commit E est rejoué comme E’ (nouveau SHA, même contenu) après le commit D de votre collègue. L’historique reste linéaire.
Ensuite, poussez normalement :
git pushSi des conflits apparaissent
Section intitulée « Si des conflits apparaissent »Pendant le rebase, Git peut rencontrer des conflits :
-
Résolvez les conflits dans chaque fichier
Fenêtre de terminal git status# Éditez les fichiers listés sous "Unmerged paths" -
Ajoutez les fichiers résolus
Fenêtre de terminal git add fichier-resolu.py -
Continuez le rebase
Fenêtre de terminal git rebase --continue -
Poussez
Fenêtre de terminal git push
Pour annuler le rebase en cours et revenir à l’état d’avant :
git rebase --abortAlternative : git pull (merge)
Section intitulée « Alternative : git pull (merge) »Si vous préférez un merge classique au lieu d’un rebase :
git pullCela crée un commit de merge :
A — B — C — D ——— M (merge commit) \— E ─┘Résultat fonctionnel identique, mais l’historique contient un point de fusion supplémentaire. Le push fonctionne ensuite normalement.
Configurer pull.rebase par défaut
Section intitulée « Configurer pull.rebase par défaut »Pour ne plus avoir à taper --rebase à chaque pull :
git config --global pull.rebase trueVérification :
git config --global pull.rebase# trueDésormais, git pull fera automatiquement un rebase au lieu d’un
merge.
Quand utiliser —force-with-lease
Section intitulée « Quand utiliser —force-with-lease »--force-with-lease force le push mais vérifie d’abord que
personne n’a poussé entre-temps. C’est un « force push sécurisé ».
Cas légitimes
Section intitulée « Cas légitimes »| Situation | Pourquoi le push est rejeté | Solution |
|---|---|---|
Vous avez fait --amend sur un commit déjà poussé | Le SHA a changé | --force-with-lease |
Vous avez fait un rebase -i sur une branche poussée | Les SHA ont changé | --force-with-lease |
Vous avez fait un reset sur une branche poussée | Des commits ont disparu | --force-with-lease |
git push --force-with-leaseDifférence avec —force
Section intitulée « Différence avec —force »| Commande | Comportement |
|---|---|
git push --force | Écrase le remote sans vérification — dangereux |
git push --force-with-lease | Vérifie que le remote n’a pas changé depuis votre dernier fetch — sûr |
Diagnostiquer une divergence
Section intitulée « Diagnostiquer une divergence »Quand la situation est confuse, diagnostiquez avant d’agir :
Voir l’état des branches locale vs remote
Section intitulée « Voir l’état des branches locale vs remote »git fetchgit log --oneline --left-right HEAD...origin/mainSortie typique :
< a1b2c3d (HEAD -> main) votre commit local< d4e5f6a votre commit local> f7a8b9c (origin/main) commit du remote> 1234abc commit du remote<= commits présents localement mais pas sur le remote>= commits sur le remote mais pas localement
Compter les commits d’écart
Section intitulée « Compter les commits d’écart »git rev-list --count HEAD..origin/main# Nombre de commits que le remote a en plus
git rev-list --count origin/main..HEAD# Nombre de commits que vous avez en plusVisualiser le graphe
Section intitulée « Visualiser le graphe »git log --oneline --graph --allCela montre clairement où les branches ont divergé.
Cas spécial : push rejeté après un rebase local
Section intitulée « Cas spécial : push rejeté après un rebase local »Si vous avez rebasé votre feature branch sur main localement, les SHA
de vos commits ont changé. Le push sera rejeté car le remote a les
anciens SHA :
# Vous avez fait :git switch feature/logingit rebase main
# Le push est rejeté :git push# ! [rejected] feature/login -> feature/login (non-fast-forward)Solution — c’est un cas légitime pour --force-with-lease (si vous
êtes seul sur cette branche) :
git push --force-with-leaseDépannage : problèmes courants
Section intitulée « Dépannage : problèmes courants »| Symptôme | Cause probable | Solution |
|---|---|---|
rejected après pull --rebase | Conflit non résolu pendant le rebase | git rebase --continue après résolution, ou git rebase --abort |
--force-with-lease aussi rejeté | Quelqu’un a poussé depuis votre dernier fetch | git fetch puis réessayez, ou faites pull --rebase |
| Push rejeté sur une branche que personne ne touche | Votre tracking branch est mal configurée | git push -u origin feature/login |
everything up-to-date mais les commits manquent | Vous n’êtes pas sur la bonne branche | Vérifiez git branch et git log --oneline -5 |
| Push OK mais les commits n’apparaissent pas sur GitHub | Poussé sur la mauvaise branche distante | git push origin feature/login:feature/login |
À retenir
Section intitulée « À retenir »- Push rejeté = le remote a avancé — c’est normal en équipe
git pull --rebaserésout 90% des cas en gardant un historique linéaire--force-with-leaseest le force push sécurisé — uniquement après un amend/rebase sur une branche personnelle- Jamais
--forcesur une branche partagée pull.rebase = trueévite d’avoir à taper--rebaseà chaque fois- Diagnostiquez avec
git log --left-right HEAD...origin/mainavant d’agir dans le doute