Des lignes de code en double après un merge
Ce qui vient de se passer
Git fusionne ligne par ligne, il ne comprend pas le code. Trois causes classiques : un conflit résolu en gardant les deux côtés ; le même code ajouté dans les deux branches à des endroits un peu différents (Git garde les deux, sans aucun conflit) ; ou le même changement apporté deux fois (cherry-pick, puis merge de toute la branche).
Risques potentiels
- Ça peut compiler mais s'exécuter deux fois (un gestionnaire d'événement enregistré deux fois, un double appel de paiement…).
- Ou casser le build avec des déclarations en double.
Avant d'exécuter quoi que ce soit
- N'annule pas le merge à l'aveugle : trouve d'abord quelle copie est la bonne.
- Après chaque merge, compile et lance les tests avant de pousser.
- Règle d'or : avant toute commande destructrice, crée une branche de secours avec git branch backup/before-fix — ça ne coûte rien.
Étapes de récupération
- 1
Voir exactement ce que le merge a changé
Juste après le merge, ORIG_HEAD est ta branche avant celui-ci. Sinon, compare avec le premier parent du commit de merge (HEAD^1).
Sans risque$ git diff ORIG_HEAD HEAD -- path/to/file# later on:$ git diff HEAD^1 HEAD -- path/to/file - 2
Trouver qui a ajouté chaque copie
blame sur les lignes en double montre le commit de chaque copie : tu sauras quelle branche a apporté laquelle.
Sans risque$ git blame -L 10,60 path/to/file - 3
Chercher des marqueurs de conflit oubliés
Une résolution trop rapide laisse souvent les deux côtés ET les marqueurs.
Sans risque$ git grep -n -e "<<<<<<<" -e ">>>>>>>" - 4
Corriger à la main (marche poussé ou non)
Supprime la mauvaise copie, compile, teste, puis commite la correction. L'option la plus sûre dans tous les cas.
Sans risque$ git add path/to/file$ git commit -m "fix: remove code duplicated by the merge" - 5
Pas encore poussé : refaire le merge proprement
Annule le merge, puis refais-le avec un style de conflit qui montre la version d'origine : beaucoup plus facile pour choisir.
Destructrice$ git reset --hard ORIG_HEAD$ git config --global merge.conflictStyle zdiff3$ git merge feature/my-branch - 6
Déjà poussé et très cassé : revert du merge
Annule tout le merge sans réécrire l'historique. Pour re-merger la branche plus tard, il faudra revert ce revert.
Prudence$ git revert -m 1 <merge-commit-hash>$ git push
Ces procédures sont fournies à titre informatif. Lis chaque commande et adapte-la à ta situation avant de l'exécuter. Disclaimer