Skills/modern-git-workflow/references/conflict-resolution.md

4.3 KiB

Protocole Méthodique de Résolution des Conflits de Rebase

Lors d'un git rebase origin/main, Git rejoue chaque commit de votre branche un par un au-dessus du dernier commit de la branche cible. Si un conflit survient, Git met le processus en pause. Ce document détaille la démarche méthodique et sécurisée pour résoudre les conflits sans perte de code.


1. Comprendre la Mécanique du Rebase

Contrairement à un git merge où les deux branches fusionnent en créant un nouveau commit de fusion, le rebase déplace la racine de votre branche. Dans les marqueurs de conflit lors d'un rebase :

  • <<<<<<< HEAD représente le code de la branche cible (origin/main) sur lequel vous êtes en train de vous caler.
  • ======= sépare les deux versions.
  • >>>>>>> <votre_commit> représente le code que votre commit essayait d'appliquer.

2. Le Protocole en 5 Étapes

[Conflit détecté] 
       │
       ▼
 1. git status (Cartographier les fichiers "both modified")
       │
       ▼
 2. Résoudre les marqueurs de conflit dans l'éditeur (<<<<<<<, =======, >>>>>>>)
       │
       ▼
 3. git add <fichier_résolu> (Ne JAMAIS faire git commit !)
       │
       ▼
 4. git rebase --continue
       │
       ▼
 5. Lancer la suite de tests (pytest, npm test...) ➔ Validation finale

Étape 1 : Cartographier les Conflits

Dès que Git indique CONFLICT (content): Merge conflict in ..., inspectez l'état :

git status

Repérez les fichiers sous la section Unmerged paths: marqués en both modified:.


Étape 2 : Résolution Sémantique

Ouvrez chaque fichier en conflit dans votre éditeur. Analysez les deux blocs :

<<<<<<< HEAD
// Code présent sur origin/main (modifié par un autre contributeur ou une autre PR)
const sessionTimeout = 3600;
=======
// Votre modification issue du commit en cours de rejeu
const sessionTimeout = 7200;
const gracePeriod = 30;
>>>>>>> 3a8f1b2 (feat(auth): increase session timeout and add grace period)

Conservez la logique métier appropriée, supprimez les marqueurs <<<<<<<, =======, et >>>>>>>, et sauvegardez.


Étape 3 : Marquer comme Résolu (Stage)

Ajoutez les fichiers résolus à l'index Git :

git add src/auth/session.js

[!CAUTION] Ne jamais exécuter git commit pendant un rebase ! L'exécution d'un commit manuel dans cet état briserait la séquence du rebase. Vous devez exclusivement utiliser git rebase --continue.


Étape 4 : Poursuivre le Rebase

Demandez à Git de rejouer les commits suivants :

git rebase --continue
  • Si Git s'arrête à nouveau sur un autre commit, répétez les étapes 1 à 4.
  • Lorsque tous les commits sont rejoués avec succès, Git affiche : Successfully rebased and updated refs/heads/<votre_branche>.

Étape 5 : Validation et Push Sécurisé

Avant tout push, validez que l'application compile et que tous les tests passent :

# Exemple pour Node / TypeScript
npm run lint && npm test

# Exemple pour Python
ruff check . && pytest

Poussez ensuite la branche vers le remote. Puisque l'historique a été réécrit localement, vous devez forcer le push, mais exclusivement avec --force-with-lease :

git push --force-with-lease origin feat/votre-feature

3. Gestion des Cas d'Urgence & Règles de Sécurité

⚠️ Annulation Immédiate (Rollback Propre)

Si la résolution devient confuse, incertaine ou que des conflits inattendus apparaissent :

git rebase --abort

Cette commande restaure immédiatement votre branche à son état exact avant le lancement du rebase. Aucune donnée n'est perdue.

🚫 Interdiction de git rebase --skip sans Audit

Ne lancez git rebase --skip que si et seulement si le commit en cours de rejeu a été intégralement intégré dans la branche cible par une autre PR, rendant votre commit complètement vide. Lancer --skip à la légère efface purement et simplement le travail contenu dans ce commit.

🔍 Cas Particulier : Commit Devenu Vide

Si votre commit est devenu vide parce que ses changements sont déjà présents sur origin/main, Git vous invitera à utiliser :

git rebase --skip

Vérifiez toujours au préalable avec git diff HEAD origin/main que vos modifications sont bien effectives sur la branche cible avant de sauter le commit.