Git rebase : Tout ce que vous devez savoir

By Corentin BURTIN

La commande Git rebase combine deux branches de code source en une seule. La commande Git merge le fait aussi. Nous expliquons ce que fait rebase, comment l’utiliser, et quand utiliser merge à la place.

L’explosion de Git

Frustré par la lenteur des mises à jour et des commits des autres systèmes de contrôle de version, Linus Torvalds, célèbre pour son noyau Linux, a mis de côté un mois en 2005 pour écrire le sien. Il l’a nommé Git.

Des sites comme GitHub, GitLab et BitBucket ont fait la promotion de Git et en ont bénéficié de manière symbiotique. Aujourd’hui, Git est utilisé dans le monde entier, et 98 % des 71 000 personnes interrogées dans le cadre d’une enquête réalisée en 2022 utilisent Git comme système de contrôle de version.

L’une des principales décisions de conception de Git était la vitesse. En particulier, le travail avec les branches devait être aussi rapide que possible. Les branches sont un élément fondamental des systèmes de contrôle de version. Un dépôt de projet aura une branche principale ou master. C’est là que se trouve la base de code du projet. Le développement, comme les nouvelles fonctionnalités, se fait dans des branches latérales séparées. Cela empêche le travail effectué dans les branches de perturber la branche principale et permet le développement simultané de différentes parties de la base de code.

Lorsque les développements dans les branches latérales sont terminés, les changements sont transférés dans la branche principale en fusionnant la branche de développement dans la branche principale. Dans d’autres systèmes de contrôle de version, travailler avec des branches était difficile et coûteux en termes de calcul. Dans Git, le travail avec les branches est très rapide et très léger. Ce qui était autrefois un exercice fastidieux et souvent évité dans d’autres systèmes, est devenu trivial dans Git.

La commande Git rebase est un autre moyen de transférer les modifications d’une branche vers une autre branche. Les commandes merge et rebase ont des objectifs similaires, mais elles parviennent à leurs fins de différentes manières et donnent des résultats légèrement différents.

Qu’est-ce que Git merge ?

A quoi sert donc la commande Git merge ? Disons que vous avez créé une branche appelée dev-branch pour travailler sur une nouvelle fonctionnalité.

Vous faites quelques commits, et testez votre nouvelle fonctionnalité. Tout fonctionne bien. Maintenant vous voulez envoyer votre nouvelle fonctionnalité à la branche master. Vous devez être dans la branche master pour pouvoir y fusionner une autre fonctionnalité.

A lire également :   Langage de contrôle des données (DCL)

Nous pouvons nous assurer que nous sommes dans la branche master en la vérifiant explicitement avant de fusionner.

git checkout master

Nous pouvons maintenant demander à Git de fusionner la branche dev-branch dans la branche courante, qui est la branche master.

git merge dev-branch

Fusion de la branche dev-branch dans la branche master

Notre fusion est terminée pour nous. Si vous extrayez la branche master et la compilez, elle contiendra la nouvelle fonctionnalité développée. Git a en fait effectué une fusion à trois voies. Il compare les commits les plus récents dans les branches master et dev-branch, et le commit dans la branche master immédiatement avant la création de la branche dev-branch. Il effectue ensuite un commit sur la branche master.

Les fusions sont considérées comme non destructives car elles ne suppriment rien et ne modifient pas l’historique Git. La branche dev existe toujours, et aucun des commits précédents n’est modifié. Un nouveau commit est créé qui capture les résultats de la fusion à trois.

Après la fusion, notre dépôt Git ressemble à une ligne de temps avec une ligne alternative qui bifurque et revient ensuite à la ligne de temps principale.

La branche dev-branch a été incorporée dans la branche master.

Si vous avez beaucoup de branches dans un projet, l’historique du projet peut devenir confus. C’est souvent le cas si un projet a de nombreux contributeurs. Comme l’effort de développement se divise en plusieurs chemins différents, l’historique du développement n’est pas linéaire. Démêler l’historique des livraisons devient encore plus difficile si les branches ont leurs propres branches.

Notez que si vous avez des changements non validés dans la branche principale, vous devrez faire quelque chose avec ces changements avant de pouvoir fusionner quoi que ce soit avec elle. Vous pourriez créer une nouvelle branche et y commiter les changements, puis faire la fusion. Vous devrez ensuite fusionner votre branche temporaire avec la branche principale.

Cela fonctionne, mais Git possède une commande qui permet d’obtenir la même chose, sans avoir à créer de nouvelles branches. La commande stash stocke vos modifications non validées pour vous, et vous permet de les rappeler avec stash pop .

Vous les utiliserez comme ceci

stash

git merge dev-branch

stash pop

Le résultat final est une branche fusionnée, avec vos changements non validés restaurés.

Qu’est-ce que Git rebase ?

La commande Git rebase atteint ses objectifs d’une manière complètement différente. Elle prend tous les commits de la branche que vous allez rebaser et les replace à l’extrémité de la branche sur laquelle vous rebasez.

A lire également :   La différence entre les égaliseurs graphiques et paramétriques

Si l’on reprend notre exemple précédent, avant toute action, notre dépôt Git ressemble à ceci. Nous avons une branche appelée dev-branch et nous voulons déplacer ces changements vers la branche master.

Après le rebasement, cela ressemble à une ligne de temps unique et complètement linéaire de changements.

Le dev-branch a été supprimé, et les commits du dev-branch ont été ajoutés à la branche master. Le résultat final est le même que si les commits dans le dev-branch avaient été directement commits dans la branche master en premier lieu. Les modifications ne sont pas simplement ajoutées à la branche principale, elles sont « rejouées » et ajoutées fraîchement.

C’est pourquoi la commande rebase est considérée comme destructive. La branche rebasée n’existe plus en tant que branche séparée, et l’historique Git de votre projet a été réécrit. Vous ne pouvez pas déterminer ultérieurement quels commits ont été faits à l’origine dans la branche dev.

Cependant, cela vous laisse avec un historique simplifié et linéaire. Comparé à un dépôt avec des dizaines, voire des centaines de branches et de fusions, la lecture du journal Git ou l’utilisation d’une interface graphique git pour regarder un graphique du dépôt, un dépôt rebasé est un jeu d’enfant à comprendre.

Comment rebaser sur une autre branche

Essayons un exemple de rebasement git. Nous avons un projet avec une branche appelée new-feature. Nous allons rebaser cette branche sur la branche master comme ceci.

Tout d’abord, nous vérifions que la branche master n’a pas de modifications en cours.

git status

Nous vérifions la branche new-feature.

git checkout new-feature

Nous disons à Git de rebaser la branche courante sur la branche master.

git rebase master

Nous pouvons voir que nous avons toujours deux branches.

git branch

Nous retournons sur la branche master

git checkout master

Nous fusionnons la branche new-feature dans la branche courante, qui dans notre cas est la branche master.

git merge new-feature

Il est intéressant de noter que nous avons toujours deux branches après la fusion finale.

La différence est que maintenant la tête de la branche new-feature et la tête de la branche master sont configurées pour pointer vers le même commit, et l’historique Git ne montre pas qu’il y avait une branche new-feature séparée, à part le label de la branche.

Git Rebase vs. Merge : Lequel devez-vous utiliser ?

Il ne s’agit pas de choisir entre rebase et merge. Ce sont deux commandes puissantes et vous les utiliserez probablement toutes les deux. Cela dit, il y a des cas d’utilisation où rebase ne fonctionne pas vraiment bien. Réparer les erreurs causées par des erreurs en utilisant merge est désagréable, mais réparer les erreurs causées par rebase est infernal.

A lire également :   Comment trouver l'adresse IP de votre Roku ?

Si vous êtes le seul développeur à utiliser un référentiel, il y a moins de chances que vous fassiez quelque chose de désastreux avec rebase. Vous pouvez toujours rebaser dans la mauvaise direction, par exemple, et rebaser votre branche principale sur votre branche de nouvelle fonctionnalité. Pour récupérer votre branche principale, vous devrez rebaser à nouveau, cette fois de votre branche de nouvelles fonctionnalités vers votre branche principale. Cela restaurerait votre branche principale, mais avec un historique étrange.

N’utilisez pas rebase sur des branches partagées où d’autres personnes sont susceptibles de travailler. Les modifications que vous apportez à votre dépôt vont causer des problèmes à beaucoup de personnes lorsque vous pousserez votre code rebasé vers votre dépôt distant.

Si votre projet a plusieurs contributeurs, la chose la plus sûre à faire est de n’utiliser rebase que sur votre dépôt local, et non sur les branches publiques. De même, si les pull requests font partie de vos revues de code, n’utilisez pas rebase. Ou du moins, n’utilisez pas rebase après avoir créé la demande de modification. D’autres développeurs sont susceptibles de consulter vos commits, ce qui signifie que ces changements sont sur une branche publique, même s’ils ne sont pas sur la branche maître.

Le danger est que vous allez rebaser des commits qui ont déjà été poussés vers un dépôt distant, et d’autres développeurs peuvent avoir déjà travaillé sur ces commits. Votre rebasement local fera disparaître ces commits existants. Si vous poussez ces changements vers le référentiel, vous ne serez pas populaire.

Les autres contributeurs devront passer par une fusion désordonnée pour que leur travail soit repoussé vers le dépôt. Si vous repoussez ensuite leurs changements dans votre dépôt local, vous devrez alors démêler un fouillis de changements dupliqués.

Rebaser, ou ne pas rebaser ?

Le rebasement peut être proscrit dans votre projet. Il peut y avoir des objections locales ou culturelles. Certains projets ou organisations considèrent le rebasement comme une forme d’hérésie, et un acte de profanation. Certaines personnes pensent que l’historique des Git doit être un enregistrement inviolable et permanent de ce qui s’est passé. Ainsi, le rebasement peut être exclu.

Mais, utilisé localement, sur des branches privées, rebase est un outil utile.

Poussez après avoir rebasé, et limitez-le aux branches où vous êtes le seul développeur. Ou du moins, où tout développement a été arrêté, et où personne d’autre n’a basé un autre travail sur les commits de votre branche.

Faites cela et vous éviterez tout problème.

Laisser un commentaire