Les branches sont une fonctionnalité essentielle du suivi de version de Git et sont utilisées en permanence par les équipes travaillant sur la même base de code. Nous allons voir comment elles fonctionnent et comment vous pouvez les utiliser pour améliorer votre flux de travail Git.
Que sont les branches, vraiment ?
Les branches sont utilisées pour séparer l’historique de Git. Vous pouvez considérer les commits Git comme une ligne de changements remontant dans le temps. Vous pouvez « checkoutter » n’importe lequel de ces commits et déplacer votre répertoire local dans le temps jusqu’à l’état où il se trouvait lorsque ce commit a été fait.
Les branches sont généralement utilisées pour travailler sur des fonctionnalités expérimentales, ou des changements qui prennent un certain temps, ou toute autre chose qui pourrait autrement casser le dépôt. Par exemple, vous pouvez travailler sur le remaniement d’un composant important de votre base de code, et jusqu’à ce que ce soit fait, vous voulez que la branche principale soit stable.
Une fois que la nouvelle branche de fonctionnalité est stable, elle peut être réintégrée dans master, souvent par le biais d’une pull request, qui est un processus permettant de réviser et de tester le code avant d’effectuer des changements.
Cependant, sous le capot, les branches fonctionnent un peu différemment de ce que l’on pourrait croire à première vue. Dans Git, les branches ne sont que des étiquettes, ou des pointeurs, vers un commit spécifique. C’est tout, la branche master pointe simplement vers le dernier commit effectué sur master ; lorsque vous effectuez un nouveau commit, l’étiquette est mise à jour pour pointer vers le nouveau commit.
Bien qu’il soit utile de penser que les commits avancent dans le temps, en réalité, les commits Git pointent en arrière les uns vers les autres. Chaque commit a une référence au dernier commit, et cette chaîne est utilisée pour construire l’état du dépôt.
Cependant, si vous créez une nouvelle branche, les choses fonctionnent un peu différemment. Quelle que soit la branche que vous avez extraite (avec git checkout ), elle sera utilisée comme étiquette pour le nouveau commit.
Pour créer la branche dans cet exemple, vous devez d’abord vous assurer que votre HEAD de dépôt est défini sur la branche master. C’est parce que vous pouvez faire des branches à partir de n’importe où – y compris les commits passés ou les commits sur d’autres branches.
À lire également : Comment définir des variables dans vos pipelines GitLab CI
git checkout master
Ensuite, créez une nouvelle branche, et faites un swap vers celle-ci :
git branch feature
git checkout feature
À ce stade, rien dans votre dépôt n’a changé. Les étiquettes des branches feature et master pointent toutes deux vers le même commit.
Cependant, tout ce que vous commettez à partir de ce moment sera ajouté à la branche feature. Plus précisément, un nouveau commit sera créé, configuré pour pointer vers le commit actuel, et l’étiquette « feature » sera mise à jour pour pointer vers ce nouveau commit.
Vous pouvez même vérifier master et faire plus de commits sur la branche principale. Cela n’affectera pas la branche feature, car tout ce que l’étiquette sait est qu’elle pointe vers ce commit spécifique. Il ne sera pas mis à jour avec le label master.
Fusion et rebasage
Bien sûr, les branches ne seraient pas très utiles si elles restaient bloquées pour toujours, c’est pourquoi Git fournit des outils pour les fusionner à nouveau dans la branche principale. Techniquement, vous pouvez fusionner des sous-branches dans n’importe quelle autre branche, tant que les historiques sont compatibles.
Le cas le plus simple est celui où vous avez une branche simple qui a juste besoin d’être fusionnée. Vous pouvez vérifier la branche master, puis exécuter git merge feature pour « rejouer » tous les commits effectués sur la branche feature sur master.
Cela les incorpore dans la ligne de temps principale et crée un nouveau « commit de fusion » avec les changements.
Ce n’est cependant pas toujours aussi simple, et dans de nombreux cas, vous aurez des conflits de fusion qui devront être résolus. Il peut s’agir de branches qui modifient les mêmes lignes dans les fichiers, de déplacements ou de suppressions de fichiers, ou d’autres types de bogues qui surviennent lorsque le logiciel est modifié depuis la création de la branche de fonctionnalité.
Si vous avez une branche de fonctionnalité qui dure depuis longtemps, une façon de minimiser ce problème est d’effectuer des fusions fréquentes, en sens inverse cette fois, du maître vers la fonctionnalité. Cela permet de maintenir la branche feature à jour et, bien que cela ne réduise pas vraiment la charge de travail requise, cela évite qu’elle ne s’accumule en un énorme désordre.
Cette stratégie est courante pour les branches à longue durée de vie et est généralement considérée comme une bonne pratique pour Git.
Un autre outil qui est également utilisé dans ce scénario est le rebasement. Fondamentalement, le rebasage revient à prendre la branche entière et à la déplacer pour commencer à un nouvel emplacement, souvent le dernier commit du dépôt. Cela conduit à un historique Git plus propre dans certains cas et est la solution préférée pour certaines situations compliquées.
Cependant, l’historique Git est « immuable », et à cause de cela, le rebasage copie les commits au lieu de les déplacer réellement. Cela peut conduire à de nombreux problèmes sur les branches partagées, si ce n’est pas coordonné correctement avec votre équipe – si vous rebasez, et que votre collègue fait un nouveau commit sur l' »ancienne » branche, maintenant supprimée, il sera laissé en plan. Il devra cacher le commit et l’ouvrir sur la nouvelle branche pour réconcilier les changements.
Comment utiliser les branches ?
Pour commencer à créer une nouvelle branche, vous devez mettre votre référentiel dans l’état approprié afin que l’étiquette de la nouvelle branche commence là où vous le souhaitez. Si vous faites une branche à partir de master, il suffit de vérifier la branche entière pour commencer au dernier commit. Sinon, vous pouvez mettre votre dépôt dans un état HEAD détaché en extrayant un commit individuel.
git checkout master
git checkout aa3e570923b8ee614cec17d9033faab4f084a6
Ensuite, vous pouvez créer la nouvelle branche, et passer à celle-ci avec checkout :
git branch feature
git checkout feature
Ceci peut être fait en une seule commande, avec l’option -b de checkout :
git checkout -b feature
A ce stade, toutes les modifications faites dans votre dépôt seront faites dans la nouvelle branche.
Si vous avez besoin de changer de branche à nouveau, il suffit de lancer git checkout master pour revenir à la normale.
Si vous avez des changements locaux que vous devez déplacer, vous pouvez les mettre dans git stash. Les changements seront stockés et pourront être réappliqués après avoir échangé les branches.
git stash
git checkout feature
git stash apply