> Comprendre git rebase (vs merge), le rebase interactif (squash, reword, drop), git cherry-pick, la résolution des conflits et la règle d'or : ne jamais rebaser un historique public déjà poussé.

*Source : https://coder-studio.com/outils/git-rebase-cherry-pick/*

---

[// GitHub & Git](https://coder-studio.com/outils/)

# git rebase et cherry-pick expliqués

Par **Kévin Papot** · publié le 24 février 2026

`git rebase` et `git cherry-pick` sont deux commandes qui réécrivent l’historique d’un dépôt Git. Bien maîtrisées, elles produisent un historique propre et linéaire, facile à relire. Mal utilisées, elles peuvent semer la confusion dans une équipe. Ce guide explique leur fonctionnement, quand les employer, comment résoudre les conflits qu’elles génèrent, et surtout la **règle d’or** à ne jamais transgresser. Si les bases de Git vous manquent, commencez par notre article sur les [commandes Git essentielles](https://coder-studio.com/outils/commandes-git-essentielles/).

## Qu’est-ce que rebaser ?

Rebaser, c’est **déplacer** une série de commits pour les rejouer à partir d’un autre point de départ. Là où `merge` fusionne deux branches en créant un commit de fusion, `rebase` réapplique vos commits un à un au sommet de la branche cible, comme si vous aviez travaillé à partir de sa dernière version.

Concrètement, imaginez une branche `feature` partie de `main`. Entre-temps, `main` a avancé. Deux façons d’intégrer ces nouveautés :

```
# Depuis la branche feature
git rebase main
```

Git prend vos commits de `feature`, les met de côté, avance `feature` au niveau de `main`, puis rejoue vos commits par-dessus. Résultat : un historique **linéaire**, sans commit de fusion.

## rebase contre merge

Les deux intègrent les changements d’une branche dans une autre, mais produisent un historique différent.

### La fusion (merge)

```
git checkout main
git merge feature
```

`merge` préserve l’historique exact : on voit que `feature` a existé en parallèle, et un **commit de fusion** relie les deux branches. L’historique est fidèle mais peut devenir touffu, avec de multiples branches entrelacées.

### Le rebase

```
git checkout feature
git rebase main
```

`rebase` réécrit les commits pour donner l’illusion d’un développement séquentiel. L’historique est **propre et linéaire**, plus facile à lire avec `git log --oneline --graph`.

### Lequel choisir ?

-   **merge** quand vous voulez conserver la trace fidèle de ce qui s’est passé, notamment sur les branches partagées et pour intégrer une _pull request_.
-   **rebase** pour nettoyer votre branche locale **avant** de la partager, ou pour mettre à jour votre travail avec `main` sans polluer l’historique de commits de fusion.

Une pratique répandue : rebaser sa branche de fonctionnalité sur `main` régulièrement en local, puis la fusionner une fois prête. On combine ainsi historique propre et traçabilité de l’intégration.

## Le rebase interactif

Le rebase **interactif** (`-i`) est l’outil le plus puissant pour remanier votre historique local. Il ouvre un éditeur listant les commits à retravailler.

```
# Retravailler les 4 derniers commits
git rebase -i HEAD~4
```

Git affiche une liste de ce type :

```
pick a1b2c3d Ajoute le formulaire de contact
pick e4f5g6h Corrige typo
pick i7j8k9l Ajoute la validation
pick m0n1o2p wip

# Commands:
# p, pick   = utiliser le commit
# r, reword = utiliser le commit, mais éditer le message
# e, edit   = utiliser le commit, mais s'arrêter pour l'amender
# s, squash = fusionner dans le commit précédent
# f, fixup  = comme squash mais jette le message
# d, drop   = supprimer le commit
```

On modifie les mots-clés en début de ligne pour indiquer l’action souhaitée, puis on sauvegarde et ferme l’éditeur. Git rejoue alors les commits selon vos instructions.

### squash : regrouper des commits

`squash` (ou `fixup`) fusionne plusieurs commits en un seul. Idéal pour transformer une série de « wip », « corrige typo », « oups » en un commit propre.

```
pick a1b2c3d Ajoute le formulaire de contact
squash e4f5g6h Corrige typo
squash i7j8k9l Ajoute la validation
```

Les trois deviennent un unique commit. Avec `squash`, Git vous laisse rédiger le message combiné ; avec `fixup`, il garde seulement le message du premier.

### reword : réécrire un message

`reword` conserve le contenu du commit mais vous laisse réécrire son message.

```
reword a1b2c3d Ajoute le formulaire de contact
```

Git s’arrête à ce commit et ouvre l’éditeur pour corriger le message. Parfait pour clarifier une description bâclée.

### edit : modifier le contenu d’un commit

`edit` interrompt le rebase à ce commit pour vous permettre d’en changer le contenu (ajouter un fichier oublié, corriger une ligne).

```
# Le rebase s'arrête au commit marqué "edit"
# Faites vos modifications, puis :
git add fichier-oublie.js
git commit --amend
git rebase --continue
```

### drop : supprimer un commit

Remplacer `pick` par `drop` (ou simplement supprimer la ligne) retire le commit de l’historique.

```
pick a1b2c3d Ajoute le formulaire de contact
drop m0n1o2p wip
```

### Réordonner les commits

Il suffit de **déplacer les lignes** dans l’éditeur pour changer l’ordre des commits. Git les rejouera dans le nouvel ordre — attention, cela peut générer des conflits si les commits touchent les mêmes lignes.

## git cherry-pick

`cherry-pick` applique **un commit précis** d’une branche sur votre branche actuelle, sans fusionner le reste. C’est l’outil de la sélection chirurgicale.

```
# Applique le commit a1b2c3d sur la branche courante
git cherry-pick a1b2c3d
```

Git crée un **nouveau** commit avec les mêmes modifications (mais un hash différent, puisqu’il est appliqué à un autre endroit).

### Cas d’usage typiques

-   **Rétroporter un correctif** : un bug est corrigé sur `main`, et il faut appliquer ce seul correctif sur une branche de release `v2.1`.
-   **Récupérer un commit** d’une branche abandonnée sans tout fusionner.
-   **Déplacer un commit** fait par erreur sur la mauvaise branche.

```
# Rétroporter un correctif sur une ancienne version
git checkout release-2.1
git cherry-pick a1b2c3d   # le commit de correction de bug
```

### Cherry-pick de plusieurs commits

```
git cherry-pick a1b2c3d e4f5g6h        # deux commits précis
git cherry-pick a1b2c3d^..i7j8k9l       # une plage de commits
```

Deux options utiles : `-n` (ou `--no-commit`) applique les changements sans créer de commit, pour les regrouper ; `-x` ajoute une ligne « (cherry picked from commit …) » au message, traçant l’origine.

```
git cherry-pick -x a1b2c3d
```

## Résoudre les conflits

Rebase et cherry-pick rejouent des commits : si une modification entre en collision avec l’état de la branche, Git s’arrête sur un **conflit**. La démarche est la même dans les deux cas.

Git marque les zones conflictuelles dans les fichiers concernés :

```
<<<<<<< HEAD
const titre = "Bienvenue sur le site";
=======
const titre = "Bienvenue chez nous";
>>>>>>> a1b2c3d (Change le titre)
```

La marche à suivre :

```
# 1. Voir les fichiers en conflit
git status

# 2. Éditer chaque fichier : garder la bonne version,
#    supprimer les marqueurs <<<<<<<, =======, >>>>>>>

# 3. Marquer le fichier comme résolu
git add fichier-en-conflit.js

# 4. Poursuivre l'opération
git rebase --continue     # ou : git cherry-pick --continue
```

Deux échappatoires en cas de doute :

```
git rebase --skip       # ignore le commit courant et passe au suivant
git rebase --abort      # annule tout et revient à l'état initial
```

`--abort` est votre filet de sécurité : il restaure la branche telle qu’elle était avant le rebase. Si une opération tourne mal malgré tout, `git reflog` permet de retrouver n’importe quel état antérieur — un sujet développé dans notre guide pour [annuler et défaire avec Git](https://coder-studio.com/outils/annuler-defaire-git/).

### Réduire la douleur des conflits

-   Rebasez **souvent** : de petits rebase fréquents génèrent moins de conflits qu’un gros rebase après des semaines de divergence.
-   Activez `rerere` pour que Git mémorise vos résolutions et les rejoue automatiquement : `git config --global rerere.enabled true`.
-   Faites des commits **atomiques** : un commit = un changement cohérent, plus facile à rejouer.

## La règle d’or : ne jamais rebaser du public

C’est la règle la plus importante de tout ce guide. **Ne rebasez jamais des commits déjà poussés et partagés avec d’autres.**

Rebaser réécrit l’historique : les commits changent de hash. Si un collègue a déjà récupéré ces commits, votre historique réécrit divergera du sien. Au prochain `pull`, Git verra deux historiques incompatibles, générant des doublons et une confusion générale.

```
# DANGEREUX si la branche est partagée
git checkout main
git rebase autre-branche
git push --force   # écrase l'historique distant : à proscrire sur une branche commune
```

### Le repère simple

-   **Branche locale, non poussée, ou personnelle** → rebase autorisé et recommandé pour nettoyer.
-   **Branche partagée (`main`, `develop`, une branche sur laquelle un collègue travaille)** → **jamais** de rebase. Utilisez `merge`.

Si vous devez absolument republier une branche de fonctionnalité **personnelle** après un rebase, préférez `--force-with-lease` à `--force` : il refuse le push si quelqu’un d’autre a poussé entre-temps, évitant d’écraser son travail par mégarde.

```
git push --force-with-lease
```

## À retenir

`rebase` rejoue vos commits sur une nouvelle base pour un historique linéaire ; `merge` préserve la trace exacte avec un commit de fusion. Le rebase interactif (`-i`) permet de `squash`, `reword`, `edit`, `drop` et réordonner vos commits locaux avant partage. `cherry-pick` applique un commit isolé sur la branche courante, parfait pour rétroporter un correctif. En cas de conflit, résolvez, `git add`, puis `--continue` — ou `--abort` pour tout annuler. Et surtout, gravez la règle d’or : réécrire l’historique est un plaisir tant qu’il reste **local**.

## À lire ensuite

-   [Les commandes Git essentielles à connaître](https://coder-studio.com/outils/commandes-git-essentielles/)
-   [Annuler et défaire des changements avec Git](https://coder-studio.com/outils/annuler-defaire-git/)
-   [Git ou GitHub : quelle différence ?](https://coder-studio.com/outils/git-vs-github/)
