Résolution d'un conflit de merge sur une Pull Request via `git rebase`

📌 Problématique

Sur une Pull Request GitHub, un conflit bloquant est apparu sur le fichier soft/menu.php :

"This branch has conflicts that must be resolved. Use the web editor or the command line to resolve conflicts before continuing."

La branche de travail avait été créée à partir de preprod_etudiant, qui avait continué à évoluer entre-temps — d'où le conflit sur ce fichier modifié des deux côtés.

🎯 Objectif

Résoudre le conflit sans polluer l'historique avec des fichiers modifiés par d'autres personnes sur preprod_etudiant. Un simple git merge aurait fonctionné, mais aurait ajouté au commit tous les fichiers auto-fusionnés (pas seulement ceux réellement modifiés par l'auteur de la PR).

✅ Solution retenue : git rebase

Plutôt qu'un merge classique, on utilise un rebase, qui rejoue les commits de la branche par-dessus la branche cible. Résultat : un historique propre, avec uniquement les fichiers réellement modifiés par l'auteur (ici soft/menu.php).

Merge vs Rebase

git merge git rebase
Historique Crée un commit de merge, inclut tous les fichiers fusionnés des deux branches Rejoue les commits, historique linéaire et propre
Fichiers dans le commit Tous les fichiers touchés par les deux branches Uniquement les fichiers réellement modifiés par l'auteur
Push après résolution git push normal git push --force-with-lease obligatoire

🧑‍💻 Procédure complète

# 1. Se placer sur sa branche et récupérer les mises à jour distantes
git checkout ta-branche
git fetch origin

# 2. Lancer le rebase par-dessus la branche cible (ex: preprod_etudiant)
git rebase origin/preprod_etudiant

# 3. Git signale le conflit dans le(s) fichier(s) concerné(s)
#    -> Ouvrir le(s) fichier(s), repérer les marqueurs :
#       <<<<<<< HEAD
#       ton code
#       =======
#       code de la branche cible
#       >>>>>>> origin/preprod_etudiant
#    -> Éditer pour garder ce qu'il faut, puis supprimer les marqueurs

# 4. Marquer le conflit comme résolu et poursuivre le rebase
git add soft/menu.php
git rebase --continue

# 5. Pousser l'historique réécrit (push forcé nécessaire)
git push --force-with-lease origin ta-branche

⚠️ Points clés à retenir

  • Un rebase réécrit l'historique (nouveaux hash de commits) → un git push classique sera toujours rejeté avec une erreur non-fast-forward.
  • Il faut alors utiliser git push --force-with-lease, plus sûr qu'un --force brut car il vérifie que personne d'autre n'a poussé sur cette branche entre-temps.
  • Ne jamais faire git pull après un rebase quand le push est rejeté — cela recréerait le conflit qu'on vient d'éliminer, avec un commit de merge indésirable.
  • git fetch peut être exécuté depuis n'importe quelle branche (il ne modifie pas le répertoire de travail) ; c'est le rebase (ou merge) qui doit être lancé depuis la bonne branche.
  • En cas de doute ou d'erreur pendant un rebase, on peut toujours revenir en arrière avec git rebase --abort.

📋 Erreur rencontrée et résolution

$ git push
 ! [rejected] ta-branche -> ta-branche (non-fast-forward)
error: failed to push some refs to '...'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart...

➡️ Solution : ne pas suivre le conseil du message (git pull), mais utiliser :

git push --force-with-lease origin ta-branche

Résultat : push accepté (forced update), conflit disparu de la Pull Request. ✅