par | Fév 23, 2022

Une technique pour maintenir une branche Git durant un request pull / merge

Aujourd’hui, Git est un des systèmes de contrôle de version les plus utilisés et les plus téléchargés au sein du secteur IT. Cependant, comme pour toutes les solutions, Git possède quelques lacunes qu’il est important de prendre en compte. Objectif : éviter de voir un projet d’équipe s’effondrer et d’obtenir un historique de son Git sans aucun sens après plusieurs mois de développement intenses. Cet article a vocation à proposer une vue d’ensemble du rebase et du fixup lors d’un request pull / merge (à noter : nous parlons ici de la stratégie de branching et de la stratégie de commit, et de rien d’autre).

L’article s’articule selon les points suivants :

1. Nous commencerons par examiner les avantages et les inconvénients de Git ;

2. Puis nous verrons comment contrebalancer les inconvénients (voir l’article sur les problèmes et l’analyse des solutions par l’introduction de GIT (rebase-autosquash et git commit-fixup) ;

3. Enfin, nous conclurons avec un examen de cette solution.

Par Simon PROVOST, Data Engineer chez LittleBigCode

Les avantages et les inconvénients de Git

 

Tout d’abord, Git est reconnu pour son efficacité et son ultra rapidité. Autre atout : le nombre incroyablement élevé de fonctionnalités qui permettent de repérer les changements de codes et d’observer leur impact sur le projet en votre absence. Git est une solution multiplateforme, ce qui la rend idéale pour des équipes multidisciplinaires travaillant avec des systèmes d’exploitation disparates.

Git est également solide et fiable. Enfin, une de ses armes les plus efficaces repose sur son incroyable fonctionnalité de lignes de commandes qui offrent une multitude de possibilités dont nous ne pouvons traiter qu’une partie aujourd’hui. Cependant, une solution aussi efficace n’est jamais sans défaut : Git est assez complexe à appréhender pour les débutants et son historique peut facilement devenir obscur si le désordre s’installe.

As more and more businesses are turning to ML models to get insights, organizations are attempting to integrate ML systems into their products and platforms.

Les problèmes de désordre au sein d’un historique Git

 

Quelle que soit la stratégie de branching Git utilisée, rencontrer un tel problème (voir schéma ci-dessous) rend très difficile de revenir à une fonctionnalité publiée six mois plus tôt à la suite d’un plantage en production, et d’établir facilement quelle branche est à l’origine du problème, quel commit et d’autres choses similaires.

 

Considérons maintenant les 2 cas suivants :

1. Exemple d’un problème : “Introduire un commit inutile en cas de changements nécessaires”

Ce problème vient du fait que la requête pull / merge nécessite des changements mineurs, portant par exemple uniquement sur la syntaxe et des optimisations de boucles. Si vous effectuez un nouveau commit pour un changement aussi minime, vous créez un commit inutile qui aurait été plus efficace dans une introduction propre des fonctions du commit initial.

2. Exemple d’un problème : “Introduire un commit inutile dans un développement”

En tant que développeur, j’applique la technique du commit autant que possible pour garder une trace de ce que je fais et m’assurer que, si mon ordinateur plante la nuit suivante, je retrouverai tout dans la branche initiale. Bien que cela soit une bonne pratique, il peux cependant arriver qu’après avoir réalisé un commit, je me rende compte que certaines parties de mon code auraient pu être mieux réalisées. J’effectue alors les modifications mais celles-ci sont liées au commit que j’ai effectué il y a quelques heures.

Si vous créez un nouveau commit pour un changement aussi minime, vous créez alors un commit inutile qui aurait été plus efficace s’il avait été ajouté au commit poussé plusieurs heures auparavant.

Présenter un tel désordre que personne ne peut lire ou utiliser dans son travail, après des mois de développement, équivaut à introduire depuis des mois des commits inutiles qui pourraient se révéler dangereux pour la stabilité de votre projet. C’est fantastique de travailler avec une stratégie de branching Git solide, et une convention de commit adéquate. Cependant, si on parle des contenus de vos requêtes pull / merge, ceux-ci doivent être bien conçus et une convention d’équipe doit être instaurée dès le début du projet.

Note 1 : Les problèmes ci-dessus ne doivent pas s’appliquer dans un projet avec un seul développeur, mais plutôt dans un projet d’équipe de 2 ou >2 ingénieurs permanents.nu va ici

Note 2 : La solution des deux problèmes ci-dessus est étroitement liée à la solution présentée ci-dessous. Le premier problème ne peut pas être résolu indépendamment du second, et vice-versa.

 

Quelles solutions pour éviter un tel désordre dans votre historique Git ?

La section suivante reviendra sur les exemples des problèmes relatés ci-dessus et montrera quelles commandes avancées sont idéales pour lutter facilement contre les problèmes d’introduction de désordre dans votre historique Git.

Exemple d’un problème : “Introduire un commit inutile en cas de changements nécessaires” :

La requête pull / merge nécessite des changements ; ces changements sont mineurs ; ils envoient des changements mineurs de syntaxe et des optimisations de boucles intégrées aux modifications initiales. Si vous effectuez un nouveau commit pour un changement aussi minime, vous créez un commit inutile qui aurait été plus efficace s’il avait été intégré au commit relatif à la fonctionnalité concernée.

Git commit — fixup (connue également comme « Ni vu ni connu ») est une potentielle solution.

L’option fixup de la commande Git consiste, d’après la documentation, à créer un commit qui modifie le contenu mais laisse le log inchangé. Le paramètre -m peut être utilisé pour compléter le log lors de la création du commit, mais le commentaire additionnel sera envoyé quand le commit fixup sera appliqué. [5]

Les revues de codes qui sont liées à un commit précis fixent le changement supplémentaire à ce commit (selon son commit-hash). Elles assurent qu’aucun désordre n’est introduit dans une plage de commit d’une nouvelle branche. De plus, ces fixups doivent être appliqués sur leur cible ; vous pouvez trouver des instructions sur la manière de procéder dans la sous-section du problème de l’exemple 2.

Rentrons dans l’aspect pratique :

 

D’après le court historique Git suivant, le request pull / merge nécessite de modifier le hash 9cf7eab: Le changement demandé par le reviewer portait sur le nom de classe du composant créé, celui-ci étant inadéquat.

Au départ – Voici l’historique que j’ai envoyé pour correction :

Analyse 1 – Erreur – Ci-dessous, l’historique que j’enverrai pour réexamen, incluant l’erreur d’avoir crée un nouveau commit dont je n’ai définitivement pas besoin ; la ligne en gras ou hash 8b56065 est le commit effectué par erreur.

Analyse 1 – Bonne pratique – Ci-dessous, l’historique que j’enverrai pour réexamen avec la bonne méthode de résolution du problème issu du hash 9cf7eab : la ligne en gras ou hash 8b56065 est le fixup créé. Fixup qui devra être appliqué plus tard dans sa cible pour n’y voir aucune trace de l’ajout inutile de tout commit néfaste.

Veuillez trouver ci-après la liste de commandes pour suivre ce processus :

Note 1 : Une fois ces fixups ajoutés, ils demeurent dans l’historique en tant que « commit », à la différence qu’ils auront une règle fixup spécifique jusqu’à leur application. Ce qui signifie que, lorsque ces commits fixup sont appliqués selon les règles adéquates, Git les retire et les applique à ses cibles respectives. Reportez-vous à la note 2 pour plus d’informations.

Note 2 : Après avoir appliqué ces fixups, Git va automatiquement fusionner tous les commits ayant la règle fixup adéquate dans leur cible. Le résultat obtenu est alors celui d’un historique plus propre que si des commits inutiles avaient été effectués sur le même périmètre. Référez-vous au même exemple ci-dessous pour plus d’informations et savoir comment appliquer un ou des commits avec la règle « fixup ».

Exemple d’un problème : “Introduire un commit inutile dans un développement” :

En tant que développeur, j’applique la technique du commit autant que possible pour garder une trace de ce que je fais et m’assurer que, si mon ordinateur plante la nuit suivante, je retrouverai tout dans la branche initiale. Bien que cela soit une bonne pratique, il peux cependant arriver qu’après avoir réalisé un commit, je me rende compte que certaines parties de mon code auraient pu être mieux réalisées. J’effectue alors les modifications mais celles-ci sont liées au commit que j’ai effectué il y a quelques heures.

Git rebase interactive est la solution.

D’après la documentation Attlasian, le rebasing est le procédé le plus utile et le plus facilement identifiable dans un contexte d’un workflow de fonctionnalités de branching. [6].

Alors que vous travaillez sur un projet et que vous avez créé quelques commits, vous réalisez que certaines modifications, qui ont été apportées auparavant, devraient être prises en compte. Vous les créez, mais au lieu de créer un nouveau commit, vous feriez mieux de les fixer dans le commit approprié (voir problème exemple 1, section exemple pratique). Après l’ajout d’un « fixup », vous devriez effectuer un rebase Git pour appliquer le fixup et manipuler votre historique comme vous le souhaitez.

Voyons l’aspect pratique :

D’après le bref historique Git ci-dessous, vous avez commis une erreur et vous devez retourner modifier certains commits déjà présents dans votre historique en utilisant fixup (voir l’exemple pratique, section de l’exemple 1). Cependant, plutôt que de fusionner en production tous les commits inutiles, vous devez les appliquer à leur cible respective.

Note : pour vous assurer que votre reviewer comprend ce que vous avez modifié, il est recommandé de laisser de côté les commit fixups pendant chaque phase de réexamen sur Github / Gitlab / Bitbucket, etc. Appliquez-les seulement une fois que le reviewer a accepté les changements, sinon le désordre peut rapidement s’installer.

 

Au départ – Voici l’historique que j’ai envoyé pour évaluation :

Analyse 1 – (Résultat de la section pratique de l’exemple 1) 

Analyse 2 – (Après que le reviewer a accepté le fixup et demandé qu’il soit appliqué dans leur cible pour fusion) : Le seul changement, c’est le hash du commit. Deux commits ont été fusionnés, indiquant que l’historique a été modifié. Cependant, quand cette branche est fusionnée en production, l’historique n’en est que plus propre.

Veuillez trouver ci-après la commande pour suivre ce processus :

Note 1 : Alors que l’exemple 1 ne montre pas la totalité de l’historique, les commandes ci-dessus modifieront inévitablement la façon dont l’historique est stocké, ce qui est extrêmement difficile à expliquer aux membres de votre équipe. Chez LBC internal lab, nous informons nos ingénieurs par notre chat interne afin de nous assurer que chacun est conscient de ce changement dans l’historique, au cas où quelqu’un d’autre travaillerait sur cette branche en particulier et aurait besoin de s’assurer que les mises à jour ont été faites de manière adéquate.

Note 2 : Tout ce qui est mentionné ci-dessus peut s’effectuer par le biais de GUI ; par exemple, avec Jetbrains Git VSC [7].

Note 3 : Gitlab comprend une fonctionnalité qui applique systématiquement les fixups soumis durant une analyse avant la fusion dans la production. Après avoir utilisé cette option plusieurs fois, tout fonctionne correctement. Reportez-vous à la documentation.

Comment commencer à utiliser Git de la bonne manière plutôt que de la mauvaise

 

Échouer à maintenir un historique Git propre pour votre projet pourrait mener à des pratiques apportant de la confusion dans le suivi des développement et à une baisse de motivation importante pour les (nouveaux) membres de votre équipe. Lors d’une requête pull / merge, la principale responsabilité du développeur est de conserver son historique et de s’assurer de sa maintenabilité sur le long terme. Si vous devez modifier un commit déjà présent dans l’historique, ces deux options solides et rapides s’offrent à vous : (git commit –fixup et git rebase -i –autosquash).

Utiliser rebase n’a jamais été facile car cela implique de réécrire un historique complet à un moment donné. Mais si cette tâche est effectuée proprement, elle peut alors améliorer considérablement votre travail au quotidien. L’utilisation de ces deux options efficaces va alors permettre d’augmenter la maintenabilité de votre projet. C’est pourquoi de nombreuses équipes utilisent désormais de plus en plus cette alternative.

Pour les étudiants ou débutants avec Git, je recommande fortement d’étudier ces options et de les expérimenter par vous-même. Étant un outil puissant et reconnu dans le monde des technologies de l’information, Git propose d’autres alternatives. Cependant, cette approche est la manière la plus rapide et la plus directe de garder un historique sans erreur lors d’un pull / merge.

À la lumière de cet article, vous devriez être pleinement conscient des conséquences de l’ajout de commits inutiles à votre historique lorsqu’une nouvelle branche doit être fusionnée en production. Vous devriez également être capable d’utiliser deux nouveaux paramétrages de Git qui vous aideront à maintenir un historique propre tout au long de votre projet.

Références :

[1] Eraslan, S., Rios, J., Kopec-Harding, K., Embury, S., Jay, C., Page, C., & Haines, R. (2020). Errors and Poor Practices of Software Engineering Students in Using Git. In Proceedings of the 4th Conference on Computing Education Practice 2020 (pp. 1–4).

[2] Salvatierra, H. (2019). A PROPOSAL OF AUTOMATIC QUALITY EVALUATOR FOR GIT COMMIT MESSAGES. Digital UPM.

[3] Allamanis, M., Barr, E., Bird, C., & Sutton, C. (2014). Learning natural coding conventions. In Proceedings of the 22nd ACM SIGSOFT International Symposium on Foundations of Software Engineering(pp. 281–293).

[4] Karma Convention, Online: Karma – Git Commit Msg .

[5] SCM, GIT. “Git — Git-commit Documentation.” Git — git-commit Documentation. Git , August 16, 2021. Git – git-commit Documentation .

[6] Atlassian. “Git Rebase | Atlassian Git Tutorial.” Atlassian. www.atlassian.com. Accessed September 26, 2021. git rebase | Atlassian Git Tutorial .

[7] Jetbrain, Intellij. “Version Control Window | IntelliJ IDEA.” IntelliJ IDEA Help. www.jetbrains.com, September 14, 2021. Version Control window | IntelliJ IDEA .