📌 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 pushclassique sera toujours rejeté avec une erreurnon-fast-forward. - Il faut alors utiliser
git push --force-with-lease, plus sûr qu'un--forcebrut car il vérifie que personne d'autre n'a poussé sur cette branche entre-temps. - Ne jamais faire
git pullaprè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 fetchpeut être exécuté depuis n'importe quelle branche (il ne modifie pas le répertoire de travail) ; c'est lerebase(oumerge) 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. ✅