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

122 lines
4.3 KiB
Markdown

# 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
```text
[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 :
```bash
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 :
```javascript
<<<<<<< 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 :
```bash
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 :
```bash
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 :
```bash
# 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`** :
```bash
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 :
```bash
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 :
```bash
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.