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

Merge avancé : stratégies, conflits et rerere

8 min de lecture

git rerere mémorise vos résolutions de conflits pour les rejouer automatiquement, -Xours/-Xtheirs tranche les conflits en faveur d’un côté, et --squash fusionne sans commit de merge. Ce guide couvre les techniques avancées pour les merges complexes.

Prérequis : Merge et conflits et Reset démystifié.

  • Annuler un merge en cours avec --abort sans laisser de traces
  • Favoriser une stratégie avec -Xours ou -Xtheirs pour les conflits massifs
  • Configurer rerere pour que Git mémorise vos résolutions de conflits

Si un merge produit des conflits et que vous voulez tout annuler :

Fenêtre de terminal
git merge --abort

Retour à l’état exact d’avant le git merge. Aucune modification n’est perdue.

Si le merge est déjà commité mais vous changez d’avis :

Fenêtre de terminal
# Annuler le commit de merge (crée un commit d'annulation)
git revert -m 1 HEAD

-m 1 indique quel parent garder (1 = la branche dans laquelle vous étiez).

Au lieu de résoudre manuellement chaque conflit :

Fenêtre de terminal
# En cas de conflit, garder notre version
git merge -Xours feature
# En cas de conflit, garder leur version
git merge -Xtheirs feature
  • -Xours : pour chaque conflit, garde le code de la branche courante
  • -Xtheirs : pour chaque conflit, garde le code de la branche mergée

Les fichiers sans conflit sont mergés normalement dans les deux cas.

Pour un contrôle fin, résolvez chaque fichier individuellement :

Fenêtre de terminal
# En plein conflit, garder notre version de ce fichier
git checkout --ours -- src/config.py
git add src/config.py
# Garder leur version de cet autre fichier
git checkout --theirs -- src/utils.py
git add src/utils.py
# Finaliser le merge
git commit

--squash applique toutes les modifications d’une branche sans créer de commit de merge :

Fenêtre de terminal
git merge --squash feature
# Toutes les modifications sont dans le staging
git commit -m "feat: intégrer la feature X"

Le résultat est un commit unique (pas de second parent). L’historique de la branche feature est « aplati ».

CritèreMerge normalMerge --squash
Commit de mergeOui (2 parents)Non (1 parent, commit classique)
Historique de la branchePréservéPerdu (aplati)
git log --graphMontre la divergenceLinéaire
TraçabilitéChaque commit visibleUn seul commit résumé

Quand utiliser --squash :

  • Branche feature avec beaucoup de commits WIP/debug
  • Vous voulez un historique linéaire propre
  • Les commits individuels n’apportent pas de valeur informative

“REuse REcorded REsolution” — Git mémorise comment vous résolvez un conflit et l’applique automatiquement si le même conflit se reproduit.

Fenêtre de terminal
git config --global rerere.enabled true
  1. Un conflit survient et vous le résolvez manuellement.

  2. Git enregistre la résolution dans .git/rr-cache/.

  3. Plus tard, le même conflit sur les mêmes lignes se reproduit (rebase, merge d’une autre branche…).

  4. Git applique automatiquement la résolution enregistrée.

    Resolved 'src/config.py' using previous resolution.
  5. Vérifiez et commitez :

    Fenêtre de terminal
    git diff # Vérifier la résolution
    git add .
    git commit
Fenêtre de terminal
# Voir les résolutions en attente
git rerere status
# Voir le diff des résolutions
git rerere diff
# Oublier une résolution enregistrée
git rerere forget src/config.py
# Vider tout le cache rerere
git rerere gc

Git ne peut pas merger des fichiers binaires (images, PDF, archives). En cas de conflit :

Fenêtre de terminal
# Garder notre version
git checkout --ours -- image.png
git add image.png
# Ou garder leur version
git checkout --theirs -- image.png
git add image.png

Pour des comparaisons visuelles, configurez un outil externe :

.gitattributes
*.png diff=exif
# .gitconfig
[diff "exif"]
textconv = exiftool

Merge un dépôt externe comme sous-dossier d’un projet :

Fenêtre de terminal
# Ajouter le dépôt comme remote
git remote add lib-utils https://git.example.com/lib-utils.git
git fetch lib-utils
# Merger dans un sous-dossier
git merge -s subtree --allow-unrelated-histories lib-utils/main

Pour les projets multi-repos, préférez submodules ou subtree.

SymptômeCause probableSolution
Conflits récurrents à chaque mergeBranche longue divergenteActivez rerere, mergez main plus souvent
--squash puis re-merge crée des conflitsGit ne voit pas les commits déjà intégrésSupprimez la branche après squash, ou utilisez un merge normal
rerere applique une mauvaise résolutionRésolution enregistrée incorrectegit rerere forget fichier
-Xours ne résout pas toutConflits de suppression/ajoutRésolvez manuellement avec --ours/--theirs par fichier
revert -m 1 ne fonctionne pasPas un commit de mergeUtilisez git revert SHA sans -m
  • git merge --abort pour annuler un merge en conflit
  • -Xours/-Xtheirs : résolution automatique en faveur d’un côté (uniquement les conflits)
  • --squash : merger sans commit de merge — historique linéaire
  • rerere : Git mémorise et rejoue vos résolutions de conflits
  • Pour les fichiers binaires : checkout --ours/--theirs par fichier
  • N’oubliez pas : -Xours (option) ≠ -s ours (stratégie)

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