J’avais besoin de comprendre les deux méthodes, car j’ai toujours utilisé la méthode de merge, pensant que la méthode rebase n’était pas efficace ou dangereuse. En tout cas, c’est ce que j’avais lu.
Mais la vérité est plus nuancée.
Le choix entre rebase et merge dépend de nos besoins spécifiques et de notre flux de travail. Passons donc en revue les avantages de chaque méthode.
Avantages du rebase
La première chose que vous apprenez à propos du rebase, c’est qu’il crée un historique de validations plus propre et linéaire. En fait rebase permet de réécrire l’historique.
Enfin, il élimine les validations de fusion inutiles, vous savez, les messages « Merged PR xxxx into develop » qui apparaissent après avoir fusionné une branche de fonctionnalité dans develop.
Avantages de la fusion
Tout d’abord, la méthode « merge » préserve l’historique complet du dépôt Git. Cela facilite ainsi le suivi de la mise en œuvre des fonctionnalités dans ce dépôt.
Elle facilite également la résolution des conflits, même si j’ai appris à effectuer un rebase sans difficulté du point de vue de la résolution de conflits.
Ensuite, il est plus facile d’annuler les modifications en cas d’erreur.
Enfin, elle conserve des horodatages précis des validations.
Quand utiliser rebase
La principale raison pour laquelle j’ai vu jusqu’à présent l’utilisation de rebase est de conserver un historique de projet propre et linéaire.
De plus, lorsque vous traitez des modifications plus petites et ciblées qui doivent être intégrées proprement, vous pouvez utiliser rebase. J’ai examiné l’historique des validations de plusieurs projets open source et je n’ai vu dans aucun d’entre eux de message de commit « Merged PR xxxx into develop ».
Quand utiliser Merge
Bien qu’il soit recommandé de ne pas avoir de branches à longue durée de vie, l’utilisation de merge est une meilleure option dans ce scénario.
De plus, lorsque plusieurs développeurs collaborent sur la même branche, cette méthode facilite le travail. Encore une fois, cela dépend vraiment de votre contexte. Dans une équipe travaillant sur des fonctionnalités distinctes, chaque individu devrait presque toujours travailler sur une branche distincte, spécifique à une fonctionnalité ou à une correction de bug données.
De plus, la commande merge ne réécrit pas l’historique, contrairement à la commande rebase. Utilisez-la donc lorsque vous devez conserver l’historique exact.
Certains affirment, j’étais l’un d’eux, que la commande merge facilite la résolution des conflits. Je pense toutefois que vous pouvez résoudre facilement les conflits avec la commande rebase en utilisant squash sur votre branche de fonctionnalité.
Cela s’applique lorsque vous souhaitez mettre à jour votre branche de fonctionnalité qui est en retard par rapport à develop. Oui, utilisez squash pour combiner plusieurs validations en un seul.
Si vous souhaitez vraiment conserver vos validations atomiques, si vous utilisez cette méthode de validation, alors oui, la fusion de develop dans votre branche de fonctionnalité peut être plus difficile à résoudre en cas de conflits. Cependant, les validations atomiques ne signifient pas une validation par fichier, comme je le croyais il y a quelques années.
Recommandations de bonnes pratiques
En cas de doute, il est recommandé d’utiliser le merge plutôt que le rebase en raison de son risque moindre et de ses options de récupération plus faciles. Cependant, si vous travaillez seul sur une branche de fonctionnalité et que vous ne l’avez pas encore poussée vers le dépôt distant, envisagez d’effectuer un rebase pour nettoyer vos validations avant de créer la requête de tirage.
N’oubliez pas que les deux approches intégreront correctement vos modifications. La principale différence réside dans la manière dont vous souhaitez que l’historique du projet s’affiche et comment les conflits sont gérés.
Exemples pratiques
Je vais vous présenter une série d’exemples couvrant les différents cas d’utilisation de rebase et de merge, en partant des hypothèses suivantes :
- nous travaillons sur un dépôt de code Git simple, avec un seul fichier texte
- nous voulons émuler une grande équipe avec un développement parallèle des fonctionnalités
- nous voulons tester une restauration
Configuration initiale
|
|
Scénario 1 : Développement d’une fonctionnalité
|
|
Scénario 2 : Développement parallèle des fonctionnalités
|
|
Scénario 3 : Rebase interactif pour le nettoyage
|
|
Scénario 4 : Revenir en arrière avec fusion
|
|
Scénario 5 : Revenir en arrière avec Rebase
Il existe trois variantes possibles :
Méthode A : Effectuer un rebase interactif pour supprimer des validations
|
|
Lorsque la fonctionnalité n’a pas été poussée vers un référentiel partagé, ou si votre équipe a convenu de réécrire l’historique, cette méthode peut être utilisée.
Méthode B : Effectuer un rebase sur un point antérieur
|
|
Cette variante vous aide à supprimer un commit spécifique tout en conservant tout le reste, en particulier dans le cas d’un historique complexe.
Méthode C : Effectuer un rebase avec --onto pour supprimer les validations intermédiaires
|
|
Nous utilisons --onto lorsque vous avez besoin d’une précision chirurgicale pour supprimer une série de validations au milieu de votre historique.
Scénario 6 : Effectuer un rebase complexe avec conflits
|
|
C’est le cas où, si vous avez beaucoup de validations sur la branche feature/parallel-work et beaucoup de validations sur la branche develop non reportés sur feature/parallel-work, qu’un rebase peut être difficile, car plusieurs validations sur chaque branche peuvent toucher à de mêmes fichiers.
Exécuter un squash de certains ou tous les validations sur feature/parallel-work aidera grandement à résoudre les conflits.
Quand j’ai commencé à utiliser rebase, j’avais l’impression de résoudre le même conflit vraiment trop de fois.
Règles importantes
- Ne jamais réaliser de
rebaseles branches sur lesquelles d’autres personnes travaillent. - Créer des messages de validation significatifs.
- Toujours tester après un
rebaseou unmerge.
Sources
Voici quelques articles et fils de discussion que j’ai consultés sur le sujet. Prenez le temps de les lire également.
- https://www.tempertemper.net/blog/git-rebase-versus-merge
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/about-merge-methods-on-github
- https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge/64319712
- https://www.gitkraken.com/learn/git/problems/git-rebase-vs-merge
- https://www.aviator.co/blog/rebase-vs-merge-pros-and-cons/
- https://blog.mergify.com/git-merging-vs-rebasing-the-complete-guide-for-modern-development/
- https://softwareengineering.stackexchange.com/questions/309919/merge-vs-rebase-pull-requests-on-github
- https://www.atlassian.com/git/tutorials/merging-vs-rebasing
- https://blog.git-init.com/differences-between-git-merge-and-rebase-and-why-you-should-care/
- https://www.atlassian.com/blog/git/written-unwritten-guide-pull-requests
Conclusion
Si vous souhaitez bénéficier d’une expérience d’apprentissage interactive de Git, je vous recommande le site Web Learning Git Branching. Il vous guidera, étape par étape, dans une interface Web de type CLI, pour vous permettre d’apprendre les tenants et aboutissants de Git.
Suivez-moi !
Merci d’avoir lu cet article. Assurez-vous de me suivre sur X, de vous abonner à ma publication Substack et d’ajouter mon blog à vos favoris pour ne pas manquer les prochains articles.
Photo d’Hasan Albari.