Aller au contenu principal

Merge et Rebase : Cas Avancés


Table des matières


  1. Rappel des bases
  2. Rebase interactif avancé
  3. Stratégies de merge
  4. Résoudre les conflits complexes
  5. Workflows avancés
  6. Commandes de récupération


1 - Rappel des bases



Merge vs Rebase

AspectMergeRebase
HistoriquePréservéRéécrit
CommitsMerge commitLiné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

CommandeUsage
git rebase -iRebase interactif
git merge --no-ffForcer un merge commit
git merge --squashFusionner en un commit
git rebase --ontoChanger la base
git checkout --oursPrendre notre version
git checkout --theirsPrendre leur version
git reflogHistorique des opérations

🔝 Retour à la table des matières