Chapitre 5 GitLab , aperçu de la plateforme de partage de code

GitLab est une plateforme facilitant l’utilisation de Git, qui permet de travailler de façon collaborative dans le développement informatique, par équipe ou non, pour un code qui évolue constamment. Elle comporte une dimension de réseau social du code qui permet de suivre un projet et y participer. Les utilisateurs ont par exemple un profil qui rassemble leurs différents projets.

Un projet sous GitLab se présente de la manière suivante :

Interface GitLab

Le fichier README.md s’affiche automatiquement et il est mis en forme par défaut. Il présente des informations utiles pour la compréhension de l’objectif du projet, son installation, etc. On peut naviguer dans l’arborescence d’un dépôt facilement mais certains types de fichiers s’affichent mal (ex: html car ils n’ont pas vocation à être partagés).

Les principales fonctionnalités sont présentes dans les onglets d’un projet sous GitLab :

  1. Repository: le dépôt, c’est le centre du contrôle de version
  2. Issues: espace de discussion, de suggestions ou demandes
  3. Merge Requests: suggestion de modifications en proposant au(x) gestionnaire(s) du dépôt de fusionner des branches
  4. CI/CD: espace dédié à l’intégration continue
  5. Wiki: espace de documentation collaboratif séparé des fichiers du dépôt (exemple). Cela implique que la documentation n’est pas associée à un fichier du dépôt. Il s’agit également d’un dépôt git
  6. Snippets: morceaux de code à conserver qui peuvent être utiles dans le futur.

Ce sont sur les trois premiers points que reposent l’immense majorité des fonctionnalités.

5.1 Repository

Le dépôt regroupe les principales fonctionnalités reliées au contrôle de version. Il indique les fichiers du projet et liste les commits par ordre chronologique. Le navigateur de fichier permet même de modifier/commiter directement en ligne. Pour un fichier donné, il permet d’afficher l’historique des modifications (en haut à droite). Il permet également de visualiser les branches et leur trajectoire et de les comparer entre elles avant de proposer une merge request (cf. ci-après).

5.2 Issues

C’est l’espace de discussion du projet. Un exemple sur le GitHub InseeFrLab. Par l’intermédiaire de différents sujets ou tickets, cet espace permet de :

  • signaler des bugs (à la manière d’un ticket)
  • discuter des évolutions d’un projet et proposer des changements
  • évoquer des pistes de modifications qui sont à creuser

Ces échanges prennent la forme d’un forum où les sujets sont regroupés sous la forme d’issues (problèmes) qui peuvent être identifiées grâce à des labels. Un des avantages est de pouvoir intégrer des morceaux de code ou de faire des références croisées entre les issues.

Pour ouvrir une nouvelle issue, par exemple pour discuter d’une modification avant de la proposer ou signaler un problème qu’on ne résoud pas immédiatement, on clique en haut à droite sur le bouton dédié :

Il ne faut pas hésiter à ouvrir des issues pour prévoir des modifications dans le futur, signaler des points à régler ou à avancer. C’est un outil efficace pour se répartir le travail et cela évite de nombreux échanges mail, avec l’avantage d’être archivé et visible par tous les contributeurs au projet (même ceux à venir).

Un aspect très pratique est qu’il est possible de faire référence aux issues dans les messages de commit en utilisant le numéro de l’issue précédé du signe #, par exemple #12. Dans ce cas, automatiquement, GitLab affichera une référence au commit dans la page de l’issue (et le lien url cliquable associé ! ).

Il est possible de fermer automatiquement une issue en faisant précéder l’appel d’une issue par le terme Closes. Cela peut être fait dans un message de commit ou dans la description d’une merge request. Par exemple :

Le problème des données manquantes est réglé

Closes #12

fermera automatiquement l’issue 12 sur la page sur gitlab.com du projet.

Il existe une astuce bien pratique pour automatiquement fermer une issue quand on travaille avec une branche. Si comme nom de branche, on donne xx-blablaxx est le numéro de l’issue, alors au moment de la création de la merge request, le commentaire sera automatiquement alimenté par Closes #xx. Lorsque cette merge request sera validée, #xx sera automatiquement fermée.

Enfin, il est possible d’avoir un affichage en tableau en cliquant à gauche sur Boards ou encore d’associer des issues à des milestones (jalons) qui sont des étapes permettant de suivre l’évolution d’un projet.

5.3 Exercice 4 : Ouvrir et organiser les issues

Au début d’une tâche particulière ou d’un projet, il est recommandé d’ouvrir des issues. Prenant la forme d’un espace de discussion, elles correspondront à la fin à des nouvelles fonctionnalités (en anglais, features). Les issues permettent également de signaler des bugs constatés, de se les répartir et d’indiquer s’ils sont réglés ou s’ils ont avancés.

Ces issues seront fermées au fur et à mesure que les fonctionnalités seront implémentées ou bien que vous aurez abandonné vos idées. Des labels peuvent être utilisés pour classer les issues. Il est possible de les affecter à une personne en particulier, fixer une date de rendu, etc.

Tout se passe sur la page du projet GitLab (menu déroulant à gauche) :

Exercice 4 : Premiers pas sur Gitlab

Question a. Ouverture et attribution

Ouvrir une issue concernant le fichier de votre voisin et indiquant qu’il faut corriger les majuscules et la ponctuation. Lui attribuer l’issue via @idep.

Question b. Règlement

Corriger votre fichier votre-idep.md par un commit puis un push.

Question c. Clôture

Vérifier via un pull que votre voisin a corrigé son texte et clôturer l’issue sur GitLab.

5.4 Merge requests (MR)

C’est l’espace pour gérer des fusions de branches, c’est-à-dire le fait de transmettre à la branche commune des modifications en les validant. Cela peut venir à la suite :

  • d’une ou plusieurs issues qui ont été créées et discutées
  • d’une création de branche afin de proposer d’intégrer celle-ci à la branche principale (master)

GitLab facilite énormément le travail de fusion de branches (MR). Si les modifications proposées sont faites avec méthode, cela évite le passage fastidieux par la ligne de commande. Pour créer une nouvelle merge request, on clique en haut à droite sur New Merge request. On sélectionne ensuite la branche source (celle où on a fait les modifications) et la branche target (celle qu’on veut modifier) :

On clique sur Compare branches and continue pour arriver sur la page permettant de décrire la merge request. On aide le(s) gestionnaire(s) du projet en faisant en sorte d’être explicite sur l’objectif de la merge request. On peut notamment faire référence à des issues comme #19 dans l’exemple ci-dessous. On donne un titre explicite à la merge request en ajoutant le préfixe WIP: si celle-ci n’est pas encore finalisée (permet de mentionner précocément au gestionnaire qu’on avance sur le développement d’une branche)

Une bonne pratique est de proposer les options suivantes :

  • Delete source branch when merge request is accepted: effacer la branche sur le dépôt commun pour éviter que quelqu’un l’édite alors qu’elle n’est plus d’actualité
  • Squash commits when merge request is accepted: regrouper tous les commits (potentiellement très nombreux dans l’ancienne branche) en un seul dans la branche de destination. Cela évite, sur les gros projets, des branches avec des milliers de commits. Pour les petites modifications, c’est-à-dire les branches avec peu de commits, on peut éviter cette option et laisser l’historique dans la branche fusionnée.

Vous pouvez voir, en dessous, les changements induits si la MR est acceptée. Lorsque la MR est soumise, GitLab inspecte les conflits entre les fichiers. S’il n’y a pas de conflit, la MR peut être acceptée directement depuis GitLab en cliquant sur le bouton vert Merge :

En cas de conflit, GitLab refuse le merge automatique et propose des commandes :

Il y a deux philosophies dans le domaine :

  • C’est à la personne qui propose la merge request de proposer une copie propre
  • C’est au(x) gestionnaire(s) de nettoyer et harmoniser

Les gros projets open-source fonctionnent plutôt de la première manière. Il s’agit de la pratique la plus prudente.

Dans des cas rares, vous vous devez de passer par la ligne de commande pour des MR. Suivez précisément les indications du merge locally et n’oubliez surtout pas l’option --no-ff lors de l’étape de merge sans quoi vous réécrirez l’historique, ce qui peut endommager votre dépôt.

La logique générale pour les étapes de merge locally est la suivante :

  1. On met à jour la branche locale cible origin (possible aussi via les menus RStudio en faisant un pull) puis on passe sur la branche source (là où sont les changements qu’on veut transmettre)
  2. On sélectionne à la main les modifications dans les programmes par l’intermédiaire des HEAD qui sont apparus dans les codes
  3. On applique les lignes de commande de l’étape 3 (en ligne de commande avec précaution)
  4. On transmet au dépôt partager avec un push (possible via les menus RStudio).

Le rôle de gestionnaire des merge request dans un projet collaboratif est important. Il faut absolument bannir les usages de push force qui peuvent déstabiliser les copies locales des collaborateurs. S’il est nécessaire de faire un push force, c’est qu’il y a un problème dans la branche, à identifier et régler sans faire push force

5.5 Exercice 5 : Fusionner les travaux avec des Merge Requests

Les merge requests (MR) sont sans doute la fonctionnalité la plus pratique. En ouvrant une MR, il est crucial de :

  • donner un titre explicite (comme on donne un objet à un mail)
  • donner des détails dans le message (comme pour les commit).

Le cas échéant, il est très pratique d’ajouter dans le corps du message close #xxxx est le numéro de l’issue décrivant la fonctionnalité que la MR implémente. Lorsque la MR sera fusionnée, l’issue sera automatiquement fermée et un lien sera créé entre l’issue et la MR. Ainsi, cela vous permettra de comprendre, plusieurs mois ou années plus tard, comment et pourquoi telle ou telle fonctionnalité a été implémentée.

Une fois une MR ouverte, il est précieux de solliciter une relecture. En effet, personne (même les meilleurs!) n’est à l’abri d’une erreur.

Les merge requests sont des espaces de discussion. Vous pouvez commenter une proposition de modification en particulier ou bien suggérer une modification.

Lorsqu’elles sont acceptées, les suggestions sont appliquées au moyen d’un commit. Cela permet une parfaite traçabilité des modifications.

Exercice 5 : Merge Request

Question a. Ouvrir une MR

Créez une merge request dans GitLab. Dans cette merge request, vous devez proposer d’ajouter à la branche master du dépôt commun les modifications qui ont été développées dans la branche que vous avez créée au cours de l’exercice 2. Autrement dit, vous proposez d’ajouter au fichier cadavre_exquis.md les deux phrases que vous avez écrites dans votre branche, et que votre voisin a corrigées.

Question b. Contribuer à une MR

Dans GitLab, allez dans la merge request créée par votre voisin, et contribuez à la discussion par un message donnant votre avis sur les modifications proposées. N’acceptez pas les MR, c’est l’objet du prochain exercice

Usuellement, c’est la seule responsabilité spécifique des mainteneurs : seuls eux peuvent fusionner dans master. Il leur appartient de veiller à la bonne qualité des merge requests.

Gitlab propose deux options lors du merge :

  • Delete source branch when merge request is accepted: supprimer la branche. C’est fortement recommandé car cela évite qu’un contributeur reprenne, après plusieurs mois d’inactivité d’une branche, qui aurait accumulé du retard par rapport à master, une branche
  • Squash commits when merge request is accepted: Là, vous devrez faire preuve de discernement. L’habitude est de faire des squash and merge (pratique la plus largement répandue). Cependant, il peut y avoir des cas où vous préférerez conserver l’historique des commits (c’est plus rare). Très franchement, ce sujet n’est pas le plus important.

5.6 Les groupes

Quand un projet est important, on peut créer un groupe qui permet d’avoir une arborescence de dossiers. La documentation officielle et ce poste de blog donnent quelques éléments supplémentaires