Retour au blog

Résoudre les conflits

Un conflit veut dire que Git a trouvé deux versions de la même ligne et attend que tu choisisses. Tu résoudras la plupart des conflits en moins de deux minutes une fois que tu connais le pattern.

7 avril 202612 min de lecture
GitConflictsMergeRebaseVersion Control
Résoudre les conflits
Résoudre les conflits - Comment Git gère les changements conflictuels
Résoudre les conflits - Comment Git gère les changements conflictuels

Un conflit veut dire que Git a trouvé deux versions de la même ligne et attend que tu choisisses.

Deux personnes ont modifié le même code. Ou quelqu'un a supprimé un fichier qu'une autre personne a changé. Git s'arrête et attend ta décision.

Tu résoudras la plupart des conflits en moins de deux minutes une fois que tu connais le pattern.


À quoi ressemble un conflit

Git marque le fichier avec des délimiteurs :

<<<<<<< HEAD
const API_URL = "https://api.prod.com";
=======
const API_URL = "https://api.staging.com";
>>>>>>> feature-branch

Trois sections :

  • <<<<<<< HEAD à ======= : ta branche actuelle
  • ======= à >>>>>>> : la branche entrante

Choisis une version, combine les deux, ou écris autre chose. Supprime les marqueurs quand c'est fait.


Quand les conflits arrivent

Tu verras des conflits pendant :

  • git merge
  • git rebase
  • git pull
  • git cherry-pick
  • git stash pop

Même déclencheur à chaque fois : deux branches ont modifié les mêmes lignes différemment.


Résolution étape par étape

1. Voir les fichiers en conflit

git status

Les fichiers en conflit apparaissent comme "both modified" ou "both added".

Unmerged paths:
  both modified:   src/config.js
  both modified:   src/api/client.js

2. Ouvrir le fichier

Trouve les marqueurs de conflit. Un fichier peut avoir plusieurs conflits.

function getUser(id) {
<<<<<<< HEAD
  return fetch(`/api/users/${id}`);
=======
  return axios.get(`/api/users/${id}`);
>>>>>>> feature-branch
}

3. Décider quoi garder

Option A : Garder le tien (HEAD)

function getUser(id) {
  return fetch(`/api/users/${id}`);
}

Option B : Garder l'autre (incoming)

function getUser(id) {
  return axios.get(`/api/users/${id}`);
}

Option C : Combiner les deux

function getUser(id) {
  // Using axios instead of fetch for better error handling
  return axios.get(`/api/users/${id}`);
}

Option D : Écrire autre chose

function getUser(id) {
  return httpClient.get(`/users/${id}`);
}

Supprime les marqueurs. Le fichier doit compiler.

4. Marquer comme résolu

git add src/config.js

5. Continuer

Pour merge :

git commit

Pour rebase :

git rebase --continue

Pour cherry-pick :

git cherry-pick --continue

Outils

VS Code

VS Code affiche des boutons cliquables au-dessus de chaque conflit :

  • "Accept Current Change"
  • "Accept Incoming Change"
  • "Accept Both Changes"
  • "Compare Changes"

TIP

"Compare Changes" ouvre un diff côte à côte. Utilise-le pour tout conflit de plus d'une ligne.

Git mergetool

git mergetool

Configure ton éditeur :

  • VS Code : git config --global merge.tool vscode
  • Vim : git config --global merge.tool vimdiff
  • Meld : git config --global merge.tool meld

Lazygit

Lazygit gère les conflits dans une interface visuelle. Flèches pour naviguer, raccourcis pour choisir les versions. L'article 8 couvre ça.


Patterns de conflits

Valeurs différentes

<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = 10000;
>>>>>>> feature

Choisis la bonne valeur.

Ajout vs modification

Une branche a ajouté des lignes, une autre a modifié du code proche.

function init() {
<<<<<<< HEAD
  setupLogging();
  setupDatabase();
=======
  setupDatabase();
  setupCache();
>>>>>>> feature

Tu veux les trois :

function init() {
  setupLogging();
  setupDatabase();
  setupCache();
}

Suppression vs modification

Une branche a supprimé un fichier, une autre l'a modifié.

git status
# deleted by us:   src/old-utils.js

Tes options :

  • Garder la suppression : git rm src/old-utils.js
  • Garder le fichier : git add src/old-utils.js

Conflits de renommage

Les deux branches ont renommé le même fichier avec des noms différents.

git status
# both added:      src/utils/helpers.js
# both added:      src/lib/helpers.js

Choisis un emplacement, supprime l'autre.


Réduire les conflits

Pull souvent

git pull origin main

Plus tu diverges longtemps, plus tu auras de conflits.

Garde les branches courtes Merge en quelques jours, pas en semaines.

Parle à ton équipe Deux personnes sur le même fichier ? L'une attend, ou vous divisez le travail.

Utilise des feature flags Ship derrière des flags au lieu de branches longue durée.

NOTE

Certains conflits arrivent dans toute codebase avec plusieurs contributeurs. C'est normal.


Abandonner

Tu veux recommencer ?

# Abandonner un merge
git merge --abort

# Abandonner un rebase
git rebase --abort

# Abandonner un cherry-pick
git cherry-pick --abort

Tu reviens à avant que tu commences.

WARNING

Après avoir commit un merge, abort ne marche plus. Utilise git reset --hard HEAD~1 à la place.


Conflits pendant un rebase

Le rebase rejoue les commits un par un. Tu peux tomber sur des conflits plusieurs fois.

git rebase main
# CONFLICT in file.js

# Résous le conflit
git add file.js
git rebase --continue

# Un autre conflit au commit suivant
# Résous encore
git add file.js
git rebase --continue

# Terminé

Trop galère ? Passe à merge :

git rebase --abort
git merge main
🔍 Pourquoi le rebase déclenche plus de conflits

Merge compare deux points finaux et les combine une fois.

Rebase applique tes commits un par un sur la nouvelle base. Le commit 1 peut confliter. Tu le fixes. Le commit 2 peut confliter avec le fichier modifié. Tu le fixes encore.

Pour les branches avec beaucoup de commits sur les mêmes fichiers, tu peux finir par résoudre des conflits similaires plusieurs fois. Merge règle ça en un passage.


Après avoir résolu

Avant de commit :

# Vérifie ce que tu vas commit
git diff --staged

# Lance les tests
npm test

# Build
npm run build

TIP

Une mauvaise résolution peut casser le build même si elle a l'air correcte. Teste après chaque conflit.


Cheat sheet

CommandeCe qu'elle fait
git statusVoir les fichiers en conflit
git diffVoir les détails du conflit
git add <file>Marquer comme résolu
git merge --abortAnnuler le merge
git rebase --abortAnnuler le rebase
git rebase --continueContinuer après avoir résolu
git mergetoolOuvrir l'outil de merge visuel

Ce qu'il faut retenir

Git demande ton avis quand il sait pas quoi faire. Regarde les deux versions, comprends ce que chaque changement voulait, choisis. C'est tout.

Plus tu en résous, plus tu vas vite. Après quelques dizaines, c'est du réflexe.

Prochain article : explorer l'historique avec log, diff et blame.


C'est la partie 4 de ma série "Git & GitHub en 10 articles".

Des questions ? Contacte-moi sur LinkedIn ou découvre plus sur mon blog.