Quelle est la différence entre git merge et git rebase? Laquelle de ces commandes privilégier? Nous allons voir tout cela ensemble dans cet article.
Rappel sur les branches
Avant de rentrer dans le vif du sujet, revoyons ensembles quelques bases sur les branches. Une branche est une référence vers un commit. Cette référence comprend donc un nom (nom de la branche) et un pointeur de commit (sha1). Une branche contient alors ce commit et tout les commits parents de ce dernieri.
Voici un exemple d’historique avec deux branches MASTER et DEVELOP.
Pour finir, la branche courante correspond à la branche pointé par HEAD. Si jamais HEAD pointe sur autre chose qu’une branche, alors nous somme en detached head.
Faire un merge entre deux branches
La commande git merge permet de ramener les modifications d’une branche qui à bifurqué de la branche courante. Voici un exemple ici avec master et develop.
Pour réaliser un merge, il faut:
- Se placer sur la branche de destination. C’est à dire, la branche qui vas recevoir les modification d’une autre branche: git checkout [nom_branche]
- Puis utiliser la commande: git merge [branche_a_merge]
Il existe deux cas de figure pour le merge
Commit de merge
Si les deux branches possèdent des commits propres, alors, git est obligé de faire un commit de merge pour avoir à la fois l’historique des deux branche. Donc, le commit de merge possède deux parents.
Exemple: On souhaite faire un merge de la branche develop dans la branche master:
- git checkout master
- git merge develop
un commit de merge est alors créé pour permettre d’avoir dans master, les commits de master avant le merge et les commits de develop. On note ici que G a alors deux parents (D et 2)
Le commit de merge permet de reverser les modifications d’une branche vers une autre tout en laissant l’historique explicite. la branche reversé sera toujours présente dans l’historique et ainsi il sera toujours possible de voir:
- Depuis quel commit la branche est partie
- Quels commits ont étés fait dans cette branche
- Quand les deux branches ont été mergés
Le fast-forward
Si l’historique entre les deux branches est linéaire, alors un simple faste-forward est appliqué. Cela signifie que la branche de destination vas remonter les commits pour venir au même niveau que la branche a merge. Cela n’entraîne donc pas la création d’un commit de merge.
MAJ: Depuis la version 2.24 de git, il faut utiliser la commande git switch [nom branche] pour changer de branche courante
Faire un rebase d’une branche
Rebase simple
La commande git rebase permet de rebase une branche sur une autre. Cela consiste à déplacer le point de départ de la première à la suite de la seconde:
- Se déplacer sur la branche à rebase: git checkout
- Utiliser la commande git rebase: git rebase
Attention: les deux branches doivent avoir au moins un commit en commun (ancêtre commun)
Exemple: On souhaite faire un rebase de la branche develop sur la branche master
- git checkout develop
- git rebase master
On se retrouve alors avec la branche develop qui part de master mais depuis le commit D au lieu du commit B initialement.
Rebase + fast-forward
Le rebase d’une branche sur une autre amène les deux branches dans une situation de fast-forward. Il est alors possible de les merges sans faire de commit de merge.
Exemple: à la suite du rebase précédent, on souhaite merge develop dans master
- git checkout master
- git merge develop
Un fast-forward est alors appliqué entre nos deux branches
Conclusion
Nous avons vue dans cet article la différence entre le git merge et le git rebase.
le git merge permet de ramener les modifications d’une branche dans une autre alors que le git rebase, permet quand à lui, de changer le point de départ d’une branche par rapport à une autre.
Il est important de noter que le code finale, sera le même peut importe la méthode utilisé, ce qui vas changer, c’est l’arborescence de l’historique et par conséquent ce que nous raconte cet historique.
On me demande souvent quelle méthode privilégier, Merge ou Rebase + Merge. Il n’y a pas de réponses toute faites, cela vas dépendre de votre besoin.
- Le merge, vous permet de voir au niveau de votre historique qu’il y a eu des développements fait en parallèles. Il permet aussi de voir quand les branches ont divergés et quand ils on été fusionnés.
- Le rebase, permet d’avoir un historique linéaire. on l’utilise quand on a pas besoins de savoir que les deux branches on été fait en parallèles. C’est le cas par exemple quand vous allez récupérer des modifications du dépôt distant et que vous avez des commit en local. utilisez alors le git pull –rebase pour utiliser la politique de rebase au lieu du merge par défaut.
Ressources
➽ Slides