Merge et Rebase : Cas Avancés
Table des matières
- Rappel des bases
- Rebase interactif avancé
- Stratégies de merge
- Résoudre les conflits complexes
- Workflows avancés
- Commandes de récupération
1 - Rappel des bases
Merge vs Rebase
| Aspect | Merge | Rebase |
|---|---|---|
| Historique | Préservé | Réécrit |
| Commits | Merge commit | Linéaire |
| Sécurité | ✅ Toujours sûr | ⚠️ Branche locale seulement |
Règle d'or du Rebase
⚠️ Ne JAMAIS rebaser une branche qui a été partagée (push).
Si d'autres ont basé leur travail dessus, utilisez merge.
🔝 Retour à la table des matières
2 - Rebase interactif avancé
Lancer un rebase interactif
git rebase -i HEAD~5
# ou
git rebase -i abc1234
Les commandes disponibles
pick = utiliser le commit
reword = modifier le message
edit = s'arrêter pour modifier
squash = fusionner avec le précédent
fixup = fusionner, ignorer le message
drop = supprimer le commit
Exemple : Réorganiser les commits
État initial :
pick abc1234 feat: add login
pick def5678 fix: typo
pick ghi9012 feat: add logout
pick jkl3456 fix: another typo
Réorganisé :
pick abc1234 feat: add login
pick ghi9012 feat: add logout
squash def5678 fix: typo
squash jkl3456 fix: another typo
Modifier un commit ancien
git rebase -i HEAD~3
# Marquer le commit comme "edit"
Après avoir sauvegardé :
# Modifier les fichiers
git add .
git commit --amend
# Continuer le rebase
git rebase --continue
Diviser un commit
git rebase -i HEAD~3
# Marquer le commit comme "edit"
Puis :
# Annuler le commit mais garder les modifications
git reset HEAD~1
# Commiter en plusieurs fois
git add file1.js
git commit -m "feat: part 1"
git add file2.js
git commit -m "feat: part 2"
git rebase --continue
🔝 Retour à la table des matières
3 - Stratégies de merge
Fast-forward (défaut si possible)
git merge feature
Avant:
D---E main
\
A---B feature
Après:
D---E---A---B main
No fast-forward (forcer un merge commit)
git merge --no-ff feature
Avant:
D---E main
\
A---B feature
Après:
A---B
/ \
D---E-------M main
Avantage : L'historique montre clairement où la feature a été intégrée.
Squash merge
git merge --squash feature
git commit -m "feat: complete feature"
Avant:
D---E main
\
A---B---C feature
Après:
D---E---F main
│
└── Contient tous les changements de A+B+C
Ours et Theirs
# En cas de conflit, prendre notre version
git merge -X ours feature
# Prendre leur version
git merge -X theirs feature
🔝 Retour à la table des matières
4 - Résoudre les conflits complexes
Comprendre les marqueurs
<<<<<<< HEAD
Votre code (branche actuelle)
=======
Leur code (branche à merger)
>>>>>>> feature/xyz
Conflits avec 3 sections
<<<<<<< HEAD
Votre version
||||||| parent
Version commune originale
=======
Leur version
>>>>>>> feature
Activer ce mode :
git config --global merge.conflictStyle diff3
Outils de résolution
# Utiliser un outil graphique
git mergetool
# Voir les versions
git checkout --ours file.txt # Votre version
git checkout --theirs file.txt # Leur version
git checkout --merge file.txt # Revenir au conflit
Voir les conflits restants
git diff --check
Annuler en cas de problème
# Annuler le merge
git merge --abort
# Annuler le rebase
git rebase --abort
Résoudre sans marquer comme résolu
# Marquer manuellement comme résolu
git add file.txt
# Continuer
git merge --continue
# ou
git rebase --continue
🔝 Retour à la table des matières
5 - Workflows avancés
Workflow "Rebase avant merge"
Le plus propre pour les feature branches :
# 1. Mettre à jour main
git checkout main
git pull origin main
# 2. Rebaser la feature sur main
git checkout feature/login
git rebase main
# 3. Résoudre les conflits si nécessaire
# (pour chaque commit)
git rebase --continue
# 4. Forcer le push (branche privée!)
git push --force-with-lease origin feature/login
# 5. Merger dans main (fast-forward)
git checkout main
git merge feature/login
Workflow "Squash et merge" (GitHub style)
# Sur GitHub : Squash and merge
# Localement :
git checkout main
git merge --squash feature/login
git commit -m "feat: implement login (#123)"
Rebase --onto
Changer la base d'une branche :
# Situation : feature basée sur develop, mais doit être basée sur main
#
# A---B---C feature
# /
# D---E---F develop
# /
# G---H main
git rebase --onto main develop feature
# Résultat :
# A'--B'--C' feature
# /
# G---H main
# \
# E---F develop
🔝 Retour à la table des matières
6 - Commandes de récupération
Annuler un merge
# Si pas encore commité
git merge --abort
# Si déjà commité
git reset --hard HEAD~1
Annuler un rebase
# Pendant le rebase
git rebase --abort
# Après le rebase (avec reflog)
git reflog
git reset --hard HEAD@{5}
Revenir à l'état avant rebase
# Trouver le point avant rebase
git reflog
# Chercher "rebase (start)" ou le dernier état de votre branche
# Revenir
git reset --hard HEAD@{n}
Récupérer des commits perdus
# Voir tous les commits (même orphelins)
git reflog
# Créer une branche pour les sauver
git branch recovered HEAD@{5}
Résumé des commandes avancées
| Commande | Usage |
|---|---|
git rebase -i | Rebase interactif |
git merge --no-ff | Forcer un merge commit |
git merge --squash | Fusionner en un commit |
git rebase --onto | Changer la base |
git checkout --ours | Prendre notre version |
git checkout --theirs | Prendre leur version |
git reflog | Historique des opérations |