Git - Merge ou rebase ?

Avec Git, on a plusieurs branches et on souhaite synchroniser ces branches (par exemple intégrer les derniers commits d’une branche à une autre). Ce cas de figure est extensible pour la tâche quotidienne : mise à jour de la branche courante (git pull). La question se pose : Quelle méthode mettre en place ?

Avec Git, on a deux possibilités : rebase et merge. Rappel sur ces deux méthodes :

  • Merge permet d’avancer la branche courante en incorporant le travail d’une autre branche. Cette opération joint et fusionne les deux points de départ de ces deux branches dans un commit de fusion qui est visible dans le graphe de l’historique (point D).

merge

  • Rebase rejoue sur une branche (que l’on appelle ma_branche) les commits d’une autre branche (que l’on appelle ref_branche) dans l’ordre d’apparition à partir du point de séparation. C’est comme si tous les travaux de ref_branche avaient été réalisés sur ma_branche. Rebase est transparent dans l’historique et permet de conserver un graphe linéaire.

rebase

Les commandes sont les suivantes :

git checkout ref_branche
git rebase ma_branche

Ou

git rebase ma_branche ref_branche

Le choix entre ces deux méthodes dépend du nombre de branches à synchroniser et du nombre de corrections traitant sur un même périmètre technique. En effet, suite à un merge de plusieurs branches, le graphe historique serait difficile à comprendre. Dans la mesure où les commits de fusion n’apportent pas d’information utile, ils polluent l’historique [2]. Et si, par exemple, plusieurs corrections sont réalisées sur une même fonction, c’est pénible de rejouer tous les commits de rebase.

  • Exemple 1 : Quand un travail local est considéré comme partant d’une base obsolète. Cela peut arriver plusieurs fois par jour, quand on essaie d’envoyer au remote nos commits locaux, pour découvrir que notre version de la branche distante trackée (par exemple origin/master) date : depuis notre dernière synchro avec le remote, quelqu’un a déjà envoyé des évolutions de notre branche au serveur, du coup notre propre travail part d’une base plus ancienne, et l’envoyer tel quel au serveur reviendrait à écraser le travail récent des copains. C’est pourquoi push nous enverrait promener. Un merge (git pull) n’est pas idéale, car elle ajoute du bruit, des remous, dans le graphe de l’historique, alors qu’en fait c’est juste un coup de pas de bol dans la séquence de travail sur cette branche. Dans un monde idéal, j’aurais fait mon boulot après les autres, sur une base à jour, et la branche serait restée bien linéaire. Dans ce cas, il est préférable d’utiliser une rebase (git pull –rebase). [1]

  • Exemple 2 : La branche ref_branche représente un sprint ou une story en méthodologie agile, ou encore un ticket d’incident (issue ou bug) précis, identifié dans la gestion de tâches [1]. Il est alors préférable d’utiliser la méthode merge.

  • Exemple 3 : La branche ref_branche est dédiée pour la correction des anomalies sur la production. Il faut alors utiliser la méthode merge car il est difficile de faire un rebase si plusieurs corrections sont réalisées sur un même périmètre.

  • Exemple 4 : Rebase et fusion d’une branche sur la branche principale

rebase1

Les commandes pour parvenir à ce résultat sont les suivantes :

git rebase master ref1
git checkout ma_branche
git merge ref1
git branch -d ref1

D’autres exemples pratiques

Après le rebase suivant :

git checkout ref_branche
git rebase ma_branche

On est sur ref_branche avec un point de départ divergé F :

rebase

  • Dans l’objectif de récupérer les derniers commits sur ref_branche faits après le rebase, sans avoir mis à jour le remote, il ne faut pas faire : git pull --rebase car git comprendrait mal ce qu’il faut faire et jouerait une série de commits de ma_branche depuis le point B sur le point de départ F.

  • Afin d’envoyer au remote la branche courante (ref_branche), ce n’est pas possible de faire git push car le point de départ divergé n’est pas la suite du HEAD de la branche courante. Il faut dans ce cas écraser le HEAD de ref_branche pour obtenir une branche différente qui porte le même nom (ref_branche) avec la commande :

git push origin +HEAD:ref_branche

[1] http://www.git-attitude.fr/2014/05/04/bien-utiliser-git-merge-et-rebase
[2] http://www.miximum.fr/git-rebase.html
[3] http://git-scm.com/docs/git-rebase


Vous avez trouvé cette publication utile? Cliquer sur
Ippon
Ippon est un cabinet de conseil en technologies, créé en 2002 par un sportif de Haut Niveau et un polytechnicien, avec pour ambition de devenir leader sur les solutions Digitales, Cloud et BigData.

Ippon accompagne les entreprises dans le développement et la transformation de leur système d’information avec des applications performantes et des solutions robustes.

Ippon propose une offre de services à 360° pour répondre à l’ensemble des besoins en innovation technologique : Conseil, Design, Développement, Hébergement et Formation.

Nous avons réalisé, en 2017, un chiffre d’affaires de 31 M€ en croissance organique de 30%. Nous sommes aujourd’hui un groupe international riche de plus de 320 consultants répartis en France, aux USA, en Australie et au Maroc.
FRANCE Website LinkedIn