Travailler avec Git via RStudio et versionner son code

Tags : Autour de R, Ressources
Date :

Utiliser Git, c’est l’une des bonnes pratiques à mettre en place lorsqu’on travaille seul ou en équipe sur un projet, et que l’on souhaite en suivre l’évolution. Mais Git, c’est quoi exactement ?

Git dans les grandes lignes

Git est un outil qui permet un contrôle des versions de projets. Il est gratuit et open source. Pour l’utiliser, vous et vos collaborateurs devrez l’installer sur vos postes : télécharger et installer Git.

À la base, Git est un outil en ligne de commande, adoré par les développeurs de tous bords. MAIS on peut (quasiment) se passer de la ligne de commande en passant par des interfaces graphiques bien pensées. Et la bonne nouvelle, c’est que notre IDE préféré, RStudio, intègre Git nativement et le rend facilement accessible.

Pour la petite histoire, Git a été conçu en 2005 par le finlandais Linus Torvalds, le père du noyau Linux. Quand on lui a demandé pourquoi il avait appelé son logiciel “git”, qui est à peu près l’équivalent de “connard” en argot britannique, il a répondu :

“Je ne suis qu’un sale égocentrique, donc j’appelle tous mes projets d’après ma propre personne. D’abord Linux, puis Git.”

Raconter une histoire

Git vous permet d’écrire l’histoire de votre projet, seul ou à plusieurs, via des snapshots, que l’on peut voir comme des instantanés ou photographies du dossier et des fichiers contenus que vous souhaitez suivre. Ce dossier est le repository. À chaque fois que l’on souhaite figer l’état du repository, prendre une photo, on fait ce que l’on appelle un commit.

Chaque commit enregistre un certain nombre d’informations :

  • qui a fait la modification
  • quand la modification a été réalisée
  • pourquoi la modification a été réalisée, description de la modification (via un message de commit)

Finis les fichier_v1, fichier_v2, fichier_correct, fichier_final1, … ! Avec Git, on ne modifie pas les noms de fichiers pour garder une version antérieure au cas où.

Voyager dans le temps

Git est une machine à remonter le temps. À chaque instantané pris, soit à chaque commit, correspond un identifiant unique, une succession de caractères aléatoires, que l’on appelle un hash :

Grâce à ce hash, il vous sera possible de revenir en arrière, à l’étape antérieure de votre projet correspondant à ce commit : on appelle cela faire un checkout. Cela a pour effet de modifier le repository, de revenir à la version précédente de votre projet, sans toutefois supprimer les autres commits réalisés ensuite.

On se rend donc bien compte de la puissance de cet outil. En effet, la vie d’un projet n’est pas un long fleuve tranquille : si vous êtes par exemple dans le cas où vous avez fait un commit au temps t et que vous êtes sûr de vous, mais qu’un jour, fatigué, vous avez continué à coder en faisant des erreurs difficiles à localiser et/ou à corriger, que vous ne savez plus où vous avez réalisé des modifications, il vous sera alors possible de reprendre votre projet à partir du moment où vous savez que tout fonctionnait à la perfection. Pas mal n’est-ce pas ?

On prend parfois des détours, on tombe sur des culs-de-sac et on fait demi tour. En ce sens, Git rend également plus facile le fait de pouvoir faire des choses “juste pour voir”.

Les branches Git

Les branches, c’est l’outil idéal pour faire des tests. Un projet sur Git, c’est un projet en général composé de plusieurs branches :

  • la branche dite master est spéciale, elle contient la version “propre” du code.
  • une branche dev est utilisée classiquement pour les développements, de celle-ci partent d’autres branches pour le développement de différentes fonctionnalités.

Les branches permettent un développement en parallèle, sans s’affecter entre elles. Si une branche ne mène à rien, on la supprime et on s’arrête là. Mais dans le cas où l’on est satisfait de ce que l’on a fait au sein d’une branche et qu’on veuille inclure ces nouvelles modifications (que l’on aura commitées dans la branche en question) au projet final, c’est-à-dire au “tronc” principal, par exemple à la branche dev, on fait ce que l’on appelle un merge.

Quand certaines lignes de code diffèrent lors d’un merge, cela génère un conflict : il faudra alors gérer ces lignes avant de réaliser le merge pour qu’il soit accepté.

Réaliser un backup

Git vous permet de faire un backup de votre projet versionné. Sur un serveur distant, ailleurs, on appelle cet endroit le remote. Votre remote peut être sur Github (le plus célèbre) ou sur un Gitlab auto-hébergé.

Pour récupérer un projet depuis un remote, la première fois, on effectue un clone ; comme son nom l’indique, on clone le projet, on en fait une copie que l’on récupère en local, sur notre machine. Lorsqu’on fait des commit sur son projet local, on va pouvoir les envoyer sur le remote en faisant un push. Les autre personnes connectées au remote effectueront un pull pour récupérer vos commit.

Git, un outil de collaboration

Après ces quelques descriptions, vous aurez compris que Git, en plus de permettre de suivre tout l’historique d’un projet, est un véritable outil de collaboration :

  • les commits permettent de suivre ce qui est fait sur le projet, par qui et quand
  • le remote permet à d’autres personnes d’accéder a votre projet
  • la gestion des merges permet de combiner votre travail avec celui de quelqu’un d’autre

Un petit récap’ avant de passer à la suite :

  • repository : le dossier que vous voulez surveiller
  • commit : un instant figé dans la vie de votre projet
  • hash : un identifiant unique
  • checkout : un saut dans le temps vers un commit
  • branch : un chemin parallèle
  • merge : la fusion de une ou plusieurs branches
  • conflict : des modifications concurrentes sur le même fichier, que Git ne parvient pas à gérer
  • remote : un serveur distant ayant une copie du repository
  • clone : récupérer pour la première fois le repository depuis le remote
  • pull : récupérer les nouveaux commit en local depuis le remote
  • push : envoyer ses nouveaux commit vers le remote

Git et RStudio

Maintenant que vous êtes, je l’espère, convaincu que travailler avec Git est une bonne idée, voire indispensable, regardons de plus près comment l’utiliser au sein de RStudio.

La bonne nouvelle, c’est que Git est installé nativement dans RStudio. Donc si vous êtes allergique à la ligne de commande, la fenêtre “Git” vous permet de réaliser les opérations courantes via du clic-bouton.

Configuration

Avant d’entrer dans le vif du sujet, il faut s’assurer que RStudio et Git soient bien connectés.

Dans un premier temps, indiquez à RStudio où se trouve Git sur votre ordinateur : Tools > Global Options… > Git/SVN

Il faut ensuite donner à RStudio le droit d’intéragir avec Git, et pour cela, deux protocoles sont possibles :

  • le protcole SSH : vous aurez besoin d’une clé SSH. Pour en créer une depuis RStudio : Tools > Global Options… > Git/SVN, puis cliquez sur Create RSA Key… et confirmez. Vous devriez obtenir quelque chose qui ressemble à ça :

Cliquez sur View public key et copiez la clé. Sur GitHub (ou Gitlab) , une fois connecté, cliquez sur votre avatar en haut à droite, puis SSH and GPG keys dans le menu de gauche. Cliquez ensuite sur New SSH key. Donnez-lui un nom, et remplissez le champs Key en collant la clé que vous aurez récupéré dans RStudio.

Enfin, il faudra déclarer votre identité : dans le terminal de RStudio (accessible avec ALT + MAJ + R), tapez en renseignant votre mail de connexion à Git :

git config --global user.email "[email protected]"
  • le protocole HTTP ou HTTPS : l’identification passe ici par un **token. Sur Github, cliquez sur votre avatar en haut à droite, puis Settings > Developer settings > Personal access tokens. Cliquez ensuite sur le bouton Generate new token*. Remplissez les champs et validez. Après validation, le token apparait : copiez-le car il ne réapparaîtra plus et vous ne pourrez pas le retrouver.

Pour ne pas devoir le taper à chaque fois qu’on connectera RStudio à Git (via un commit, un push, un pull ou autres), on doit le déclarer dans la configuration de Git. Dans le terminal, tapez avec l’URL qui correspond à la seconde ligne :

git config credential.helper store
git push http://example.com/repo.git

Collez le token que vous avez copié.

Attention : les tokens ont une durée de vie limitée.

Initialisation d’un projet R avec Git

Le principe de fonctionnement repose sur le fait qu’à un projet R est associé un projet Git. Il faut posséder un compte sur le remote qui va héberger vos projets versionnés, Github dans notre exemple.

Connectez-vous sur GitHub et cliquez sur Create new repository. Renseignez le nom, la description, et la confidentialité de votre projet. Ajoutez un README.md pour ajouter des instructions à suivre pour les personnes qui auront accès à votre repository sur le remote. Le nom de votre projet doit être idéalement en minuscule, sans point, espace ou underscore, et ne doit pas commencer par un chiffre. Par commodité, ce nom doit correspondre au nom de votre projet R existant ou à venir.

Vous devriez vous retrouver face à cet écran :

Pour associer ce repository Git à un projet R via RStudio, vous devez faire un clone : cliquez sur Code et copiez

  • l’URL si vous avez choisi le protocole HTTP/HTTPS
  • le SSH si vous avez choisi le protocole SSH

Dans RStudio maintenant : File > New Project… > Version Control > Git, renseignez l’URL/le SSH de votre repository que vous avez préalablement copié, le nom du projet R (le même que Git idéalement) et le dossier dans lequel le placer, enfin cliquez sur Create Project :

Dans ce nouveau projet RStudio créé, vous verrez apparaître l’onglet git en haut à droite :

Vous travaillez depuis longtemps sur un projet dans RStudio, ou vous avez quelques fichiers existants que vous souhaitez suivre via Git ? Je vous recommande fortement de lire cet article qui vous expliquera en détails comment transformer un dossier en projet Git synchronisé sur Github ou Gitlab. Pour résumer, si votre projet RStudio existait avant la création du repository sur Github, ouvrez-le et exécutez l’instruction usethis::use_git() (le package {usethis} doit etre installé). Répondez par l’affirmative à toutes les questions posées dans la console. Un premier commit “Initial Commit” est fait pour vous. RStudio redémarre et git est opérationnel en local.

Il vous faut maintenant relier ce projet à votre remote. Ouvrez le terminal Git :

Dans le terminal, saisir (ici j’ai donné l’URL de mon projet sur Git):

git remote add origin https://github.com/ElenaDatak/gitcourse.git
git push -u origin master

Vous venez de rajouter un remote et de faire un premier push.

Si les boutons push et pull (les 2 flèches verticales) du panneau Git restent grisés, cliquez sur la flèche circulaire de rafraîchissement du panneau :

Git au quotidien

Vous utiliserez majoritairement ces 3 instructions principales :

  • commit : Une fois des fichiers de votre projet modifiés, utilisez le panneau “Git” et le bouton commit pour figer un état. Un commentaire expliquant vos modifications devra être saisi.
  • push : Une fois qu’un certain nombre de commits a été effectué, afin de les envoyer sur le remote, il faut effectuer un push. Pour cela, utilisez la fenêtre “Git” et le bouton push (représenté sous la forme d’une flèche montante).
  • pull : Pour rapatrier des modifications depuis le remote, il faut faire un pull en utilisant la fenêtre “Git” et le bouton pull (représenté sous la forme d’une flèche descendante). Votre projet Rstudio est alors synchronisé avec le remote

Attention, vous ne pourez pas pusher si un autre collaborateur a pushé des modifications depuis la dernière fois que vous avez pullé. Il faudra donc faire un pull avant de faire votre push. Dans tous les cas, il est recommandé de faire un pull chaque fois, avant de reprendre votre travail sur un projet.

Le panneau Git de RStudio vous indique en temps réel l’état de votre projet : le statut des différents fichiers et dossiers sera affiché :

  • Un nouveau fichier sera associé à une icone orange contenant un ?
  • Ce nouveau fichier sera associé à une icone verte contenant un A une fois que vous l’aurez coché (dans la colonne ‘staged’)
  • Un fichier modifié sera associé à une icone bleue contenant un M
  • Un fichier effacé sera associé à une icone rouge contenant un D

Faire un commit

Vous avez créé un nouveau fichier R (via File > New File > Rscript ou CTRL + MAJ + N) et vous l’avez sauvegardé (CTRL + S). Ce fichier apparaît en tant que nouveau fichier dans le panneau Git. Cochez la case Staged et cliquez sur le bouton Commit :

Une fenêtre s’ouvre alors : vous devez écrire un message de commit. Ce message est important car il raconte l’histoire de votre projet. Cliquez ensuite sur le bouton Commit de cette fenêtre. Vous pouvez ensuite fermer la fenêtre de commit.

Pusher vos modifications

Pour l’heure les commits que vous avez faits ne sont présents qu’en local sur votre ordinateur, le remote n’est pas au courant des modifications apportées au repository. Il faut envoyer ces commits sur le serveur distant, en faisant un push. Pour cela il faut cliquer sur la flèche verte montante du panneau git :

Vous pourrez vous assurez que votre commit a bien été pushé en retournant sur le Git de votre projet :

Le .gitignore

Il est n’est pas nécessaire de versionner l’intégralité des fichiers de votre projet. Seuls ceux que vous cocherez seront associés à des commits. En ce sens, il est possible de demander explicitement à Git de ne pas surveiller tel ou tel fichier : c’est le role du fichier .gitignore qui se trouve à la racine de votre projet. Il s’agit d’un fichier texte qui accepte les expressions régulieres et permet de définir des régles qui correspondent à plusieurs fichiers :

Puller les modifications des autres

On l’a déjà dit, Git est un très bel outil de collaboration. Si d’autres personnes travaillant sur le même projet, et donc le même remote ont pushé leurs modifications, vous pourrez les récupérer en local sur votre ordinateur – et donc dans votre RStudio – en faisant un pull. Pour cela rien de plus simple : cliquez sur la flèche qui pointe vers le bas dans le panneau Git :

Une fenêtre s’ouvre et donne les informations relatives aux modifications effectuées :

Fermez la fenêtre, votre repository est maintenant à jour.

Voir l’historique des modifications

En cliquant sur Commit puis History, vous verrez la succession de commits réalisés :

Gestion des conflits

Ecrire à plusieurs en même temps sur le même fichier, même avec un outil dédié, reste quelque chose de “problématique”. Parfois les modifications que vous allez récupérer avec un pull contredisent des modifications que vous avez effectuées de votre côté en local. Il se produit alors un conflit :

Le fichier est associé à une icône orange avec un U

Le contenu du fichier peut être un peu déroutant… Les conflits sont des lignes de codes qui diffèrent d’une version à l’autre. La résolution des conflits est à la charge de l’utilisateur.

Dans le fichier on distingue des parties délimitées par des <<<< et des >>>>, et vont s’entrecroiser les lignes qui viennent des commits locaux et des commits distants.

Pour résoudre un conflit, 2 solutions :

  • Pour les cas simples, on peut éditer directement, à la main le fichier en prenant soin de bien supprimer les <<<< et >>>> (ctrl + D permet de supprimer une ligne dans RStudio). Une fois la modification effectuée, il suffit de recocher le fichier et de refaire un commit.
  • Pour les cas plus complexes, un outil peut être nécessaire. Nous allons utiliser winmerge. Pour le lancer depuis le terminal il faut lancer git mergetool

Une fenêtre s’ouvre (Ok, les couleurs ne sont pas très agréables…) :

Winmerge permet de voir simultanément les 3 fichiers, le local, le distant et celui qui sera conservé. Il dispose d’outil graphique permettant de choisir ligne à ligne les modifications à accepter ou non.

Créer une nouvelle branche

Comme pour le reste, créer une nouvelle branche est relativement simple quand on travaille sur RStudio. Dans le panneau Git, cliquez sur le bouton dédié à la création d’une nouvelle branche et nommez-la :

En gardant la case Synch branch with remote, on indique que cette nouvelle branche est une branche et locale et remote : vous pourrez la pusher sur votre remote.

Vous pouvez réaliser les opérations usuelles – commit, push, pull – sur cette nouvelle branche, comme précédemment. Ces modifications n’impacteront pas pour l’heure les autres branches : si vous retournez dans la branche master, vous verrez que les fichiers créés dans la branche n’y sont pas.

Pour changer de branche, cliquez en haut à droite sur le nom de la branche active :

Vous retrouvez votre branche sur git et pouvez également naviguer facilement entre les branches :

Merger une branche

Quand on est satisfait de ce qu’on a fait sur une branche, on souhaite rapatrier les modifications réalisées sur le “tronc”, la branche master par exemple. Sur Github, on parle de Pull Request, sur Gitlab, on parle par contre de Merge Request

Sur Github :

chec

Sur Gitlab :

Un merge request ne devrait jamais, dans l’idéal, être validé par l’auteur de la modification. Il s’agit d’une bonne occasion pour qu’une autre personne dans le projet vérifie puis accepte la modification effectuée sur ‘master’.

Des conflits peuvent là-aussi avoir lieu, ils sont à régler avant d’aller plus loin.

Voyage voyage…

Git vous permet de revenir en arrière et de voyager dans l’histoire de votre projet. Il est tout à fait possible de revenir à l’état du projet d’il y a quelques jours pour créer une nouvelle branche à cet endroit. Pour rappel, on appelle cela un checkout.

Pour vous repositionner sur un commit particulier, il vous faut trouver son hash. Il est en partie visible dans la colonne ‘SHA’ dans le volet history :

Cliquez sur le commit qui vous intéresse : le hash complet s’affichera, copiez-le, on peut alors dans le terminal effectuer un checkout

git checkout 0f457493

Si l’on souhaite effectuer des modifications à partir de ce commit il convient d’y créer une branche, afin d’éviter de perdre le contact avec les autres commits plus récents.

Pour aller plus loin


À propos de l'auteur


Commentaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *


À lire également