Aller au contenu
Développement medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Débloquer un push Git rejeté

9 min de lecture

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.

  • Comprendre pourquoi un push est rejeté (divergence de branches)
  • Résoudre le rejet avec pull --rebase puis re-push propre
  • Utiliser --force-with-lease en toute sécurité quand nécessaire
  • Diagnostiquer les divergences entre local et remote
  • Configurer pull.rebase pour éviter les merges parasites automatiques

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 branch
hint: 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.

Dans 90% des cas, la solution est simple :

Fenêtre de terminal
git pull --rebase

Cette commande fait deux choses :

  1. Récupère les nouveaux commits du remote (git fetch)
  2. 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 :

Fenêtre de terminal
git push

Pendant le rebase, Git peut rencontrer des conflits :

  1. Résolvez les conflits dans chaque fichier

    Fenêtre de terminal
    git status
    # Éditez les fichiers listés sous "Unmerged paths"
  2. Ajoutez les fichiers résolus

    Fenêtre de terminal
    git add fichier-resolu.py
  3. Continuez le rebase

    Fenêtre de terminal
    git rebase --continue
  4. Poussez

    Fenêtre de terminal
    git push

Pour annuler le rebase en cours et revenir à l’état d’avant :

Fenêtre de terminal
git rebase --abort

Si vous préférez un merge classique au lieu d’un rebase :

Fenêtre de terminal
git pull

Cela 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.

Pour ne plus avoir à taper --rebase à chaque pull :

Fenêtre de terminal
git config --global pull.rebase true

Vérification :

Fenêtre de terminal
git config --global pull.rebase
# true

Désormais, git pull fera automatiquement un rebase au lieu d’un merge.

--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é ».

SituationPourquoi 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éeLes SHA ont changé--force-with-lease
Vous avez fait un reset sur une branche pousséeDes commits ont disparu--force-with-lease
Fenêtre de terminal
git push --force-with-lease
CommandeComportement
git push --forceÉcrase le remote sans vérification — dangereux
git push --force-with-leaseVérifie que le remote n’a pas changé depuis votre dernier fetchsûr

Quand la situation est confuse, diagnostiquez avant d’agir :

Fenêtre de terminal
git fetch
git log --oneline --left-right HEAD...origin/main

Sortie 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
Fenêtre de terminal
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 plus
Fenêtre de terminal
git log --oneline --graph --all

Cela 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 :

Fenêtre de terminal
# Vous avez fait :
git switch feature/login
git 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) :

Fenêtre de terminal
git push --force-with-lease
SymptômeCause probableSolution
rejected après pull --rebaseConflit non résolu pendant le rebasegit rebase --continue après résolution, ou git rebase --abort
--force-with-lease aussi rejetéQuelqu’un a poussé depuis votre dernier fetchgit fetch puis réessayez, ou faites pull --rebase
Push rejeté sur une branche que personne ne toucheVotre tracking branch est mal configuréegit push -u origin feature/login
everything up-to-date mais les commits manquentVous n’êtes pas sur la bonne brancheVérifiez git branch et git log --oneline -5
Push OK mais les commits n’apparaissent pas sur GitHubPoussé sur la mauvaise branche distantegit push origin feature/login:feature/login
  • Push rejeté = le remote a avancé — c’est normal en équipe
  • git pull --rebase résout 90% des cas en gardant un historique linéaire
  • --force-with-lease est le force push sécurisé — uniquement après un amend/rebase sur une branche personnelle
  • Jamais --force sur une branche partagée
  • pull.rebase = true évite d’avoir à taper --rebase à chaque fois
  • Diagnostiquez avec git log --left-right HEAD...origin/main avant d’agir dans le doute

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn