class: center, middle, inverse, title-slide # L’écosystème Git ## Git : fonctionnement, outils, possibilités ### Elise Maigné ### 2022-02-18 --- class: center, middle # git c'est quoi ? <img src="images/logo_git.png", width="300" height="300"> --- # Git Un système de gestion de version (voir [Différence avec SVN](#bonus)). -- Qui permet : - De sauvegarder ses codes (si serveur distant) - De conserver l'historique des fichiers (qui a fait quoi ?) - Visualiser les changements au cours du temps - Travailler à plusieurs sur le même code - Revenir en arrière, changer d'avis, tester une solution dans une branche séparée -- .center[] .center[] --- # Pourquoi je m'y suis pas mise avant ? - 1ers mails sur git remontent à 2013 dans mon équipe et 2014 groupe RR. - J'avais vraiment du mal à comprendre comment ça marchait et ce que je pouvais faire. - J'étais perdue au milieu de tous les termes "git/push/github/tortoise". - Différence de langages entre info/stat -- </br></br> .center[ *"Elise j'ai mis en place un SVN, c'est facile tu synchronyse avec tortoise et tu push tes modifs"* ] --- class: center, middle # git et son écosystème <img src="images/logo_git.png", width="300" height="300"> --- # Ecosystème 1 #### un projet (de code) que l'on veut versionner <center> <img src="images/vocab1.png", width="90%"> </center> --- # Ecosystème 2 (facultative) #### choisir un endroit pour déposer son code <center> <img src="images/vocab2.png", width="90%"> </center> --- # Ecosystème 3 (facultative sur mac et linux) #### un logiciel plus sympa que la ligne de commande <center> <img src="images/vocab3.png", width="90%"> </center> --- # A quoi ressemble un projet versionné ? .left-column[ #### Sur ma machine : <img src="images/capture_ecran_git.png", width = "90%"> ] -- .right-column[ #### Sur [forgemia.inra.fr](https://forgemia.inra.fr/elisemaigne/2021_git/-/tree/main) : <img src="images/capture_ecran_forgemia.png", width = "60%"> ] --- class: center, middle # Git fonctionnement ## Quelques commandes de base --- # Initialisation **Prérequis : j'ai mis ma clé ssh sur un serveur distant** .pull-left[ ### Je démarre un projet sur la forge 1. Création d'un projet sur une forge (avec README) 2. Clone de ce projet sur sa machine en local ```bash git clone git@forgemia.inra.fr:elise.maigne/2021_git.git ``` ] -- .pull-right[ ### J'ai déjà un dossier en local 1. `git init` 2. Création d'un projet sur une forge (sans README) 3. "Push an existing repository" ] -- <center>
</center> --- # Les "espaces" git <center>
</center> <br/> .pull-left[ - **working directory** - **stage** - **local repository** - **remote repository** ] .pull-right[ ] --- # Les "espaces" git <center>
</center> <br/> .pull-left[ - .h3space[working directory] - **stage** - **local repository** - **remote repository** ] .pull-right[ Mon espace de travail classique, sur ma machine. Là où je code. ] --- # Les "espaces" git <center>
</center> <br/> .pull-left[ - **working directory** - .h3space[stage] - **local repository** - **remote repository** ] .pull-right[ <br/> <br/> Aussi appelé **index** ou **zone de stagging**. Un espace de transit sur lequel sont observées les modifications de fichier. ] --- # Les "espaces" git <center>
</center> <br/> .pull-left[ - **working directory** - **stage** - .h3space[local repository] - **remote repository** ] .pull-right[ <br/> <br/> <br/> Le dépôt de version local, sur ma machine. Enregistre tous les changements (commits). ] --- # Les "espaces" git <center>
</center> <br/> .pull-left[ - **working directory** - **stage** - **local repository** - .h3space[remote repository] ] .pull-right[ <br/> <br/> <br/> <br/> <br/> Le dépôt de version distant, sur une forge. Enregistre tous les changements (commits) et permet de partager son dépôt. ] --- # Un projet versionné = une succession de commits. #### Exemple sur forgemia : https://forgemia.inra.fr/elise.maigne/2021_git/-/commits/main #### Exemple avec gitk <center> <img src="images/commits_gitk.png", width="60%"> </center> --- # Un commit = un point d'étape
<img src="images/exemple_commit.png", width="80%"> --- # Un commit = un point d'étape #### 1. On indique à git qu'il doit suivre ces fichiers et on intègre les modifications au prochain commit `git add` .pull-left[ ```bash git add . ``` ] .pull-right[ ```bash git add nomFichier.R ``` ] -- #### 2. On fait un commit avec `git commit` ```r git commit -m "J'explique ce que j'ai fais comme modif" ``` -- </br> <center>
</center> --- # Et le serveur distant ? #### Envoi des derniers commits au serveur distant ```bash git push ``` <center>
</center> #### Récupération de l'état du du serveur distant ```bash git pull ``` <center>
</center> --- # Exemple de processus "simple" de travail avec git #### 1. Un projet versionné sur un serveur distant #### 2. Je travaille comme d'habitude sur mes fichiers #### 3. De temps en temps = je marque un point d'étape de mon travail : ```bash git add . git commit -m "J'explique en 2 mots ce que j'ai fait" git push ``` #### 4. Si travail à plusieurs : je récupère les modifications des autres (avant de me remettre à travailler) ```bash git pull ``` --- # Les fichiers git  - Un dossier `.git` : contient tous les fichiers de gestion de version. -- - Un fichier `.gitignore` : permet d'exclure certains fichiers ou dossiers des commits. -- Exemple de contenu d'un `.gitignore`: ```bash .Rproj.user .Rhistory .RData .Ruserdata /data ``` En particulier on ne commite pas les données. --- # Les branches La branche par défaut est **main** (feu **master**). Il est possible de créer de nouvelles branches, pour tester une autre direction, ajouter une fonctionalité. -- .pull-left[ Projet d'application à plusieurs, 1 branche = 1 fonctionalité, plusieurs fonctionalités en même temps.
] -- .pull-right[ Développement d'un package R : une branche correspond à une modification majeure du code, faite à plusieurs.
] --- # Les branches #### Création d'une branche ```bash git branch mabranche ``` #### Changer de branche ```bash git checkout mabranche git checkout monautrebranche ``` On ne peut changer de branche uniquement si toutes les modifications (des fichiers suivis) sont commitées. --- # Les branches #### Fusionner des branches ```bash git checkout main # Je me place sur main git merge mabranche # J'intègre les modifications qu'il y a sur "mabranche" ``` -- #### Les conflits Si un fichier est modifié 2 fois au même endroit. Il faut choisir entre les 2 versions pour pouvoir finaliser le merge
--- # Les branches #### A quoi ressemble un conflit ? ```bash <<<<<<< HEAD:fichier.R J'avais mis ça avant dans une branche ====== Et maintenant j'ai ça, je ne suis qu'un logiciel je ne sais pas quoi faire >>>>>>> iss53:fichier.R ``` -- #### Merge request/pull request (sur une forge) Crée une demande de rajout de code. Superviser les "merge" à l'intérieur d'un projet ou permet à une personne extérieure au projet de contribuer. - Dicussion - Gestion des conflits - Assigner à quelqu'un Vocabulaire : `merge request` chez GitLab VS `pull request` chez GitHub --- # Les forges à votre disposition - GitHuB - GitLab - pour les INRAE : forgemia.inra.fr (instance GitLab) - communauté RENATER : sourcesup.renater.fr (instance FusionForge, avec git) - communauté mathématique française : https://plmlab.math.cnrs.fr (instance GitLab) --- # Possibilités (pour des statisticiens) <style type="text/css"> .tiny .remark-code { /*Change made here*/ font-size: 70% !important; } </style> .left-column[ - .h3space[Publication, Partage du code] - **Branches** - **GitLab pages, GitHub pages** - **CI/CD (integration continue)** - **Enseignement** ] .right-column[ </br> Code bien identifié, accessible via une url. Ne pas oublier le README à la racine ! Transparence et visibilité. ] --- # Possibilités (pour des statisticiens) .left-column[ - **Publication, partage du code** - .h3space[Branches] - **GitLab pages, GitHub pages** - **CI/CD (integration continue)** - **Enseignement** ] .right-column[ </br></br></br> Se servir des branches pour tester : - une nouvelle méthode, - une hypothèse différente, - un nouveau jeu de données ] --- # Possibilités (pour des statisticiens) .left-column[ - **Publication, partage du code** - **Branches** - .h3space[GitLab pages, GitHub pages] - **CI/CD (integration continue)** - **Enseignement** ] .right-column[ </br> Faire des sites webs très facilement avec : - un code qui génère un html (ou un html dans mon dépôt) - et juste un fichier [yml](#yml) à la racine du dépôt (exemple : https://elisemaigne.pages.mia.inra.fr/2021_git/index.html) ] -- .right-column[ #### Exemple de fichier yml (nom de fichier = ".gitlab-ci.yml") : .tiny[ ```yml pages: stage: deploy # Je place le nécessaire dans un dossier public/ script: - mkdir public - cp -r presentation/* public artifacts: paths: - public # Je fais tout ça uniquement sur la branche main only: - main ``` ] ] --- # Possibilités (pour des statisticiens) .left-column[ - **Publication, partage du code** - **Branches** - **GitLab pages, GitHub pages** - .h3space[CI/CD (integration continue)] - **Enseignement** ] .right-column[ </br></br></br></br></br></br></br></br> Compiler ses rapports automatiquement. Faire des tests automatiques (ex. `R cmd CHECK`, lancer des tests unitaires, ...). Attention, c'est fait à chaque "push" --> Est-ce toujours utile ? ] --- # Possibilités (pour des statisticiens) .left-column[ - **Publication, partage du code** - **Branches** - **GitLab pages, GitHub pages** - **CI/CD (integration continue)** - .h3space[Enseignement] ] .right-column[ </br></br></br></br></br></br></br></br></br></br></br></br></br> Un projet "principal" forké (`git fork`) par les étudiants qui partent de la même copie et peuvent faire leurs propres modifications, indépendemment les un des autres. ] --- ## Vocabulaire .pull-left[ #### Au démarrage - `git clone` - `git fork` - `git init` #### Gérer les modifications de code - **`git add` + `git commit -m "Message'`** - **`git push`** - **`git pull`** #### Visualiser - `git diff` - `git blame` #### Savoir où on en est - **`git status`** ] .pull-right[ #### Branches - `git branch` - `git checkout` - `git merge` - `git rebase` #### Revenir en arrière - `git revert` #### Un mot que l'on risque de croiser en travaillant avec git - `HEAD` = pointe vers un commit (= un état du dépôt, classiquement le dernier commit de la branche sur laquelle on est) ] --- # Des points de repère <img src="images/git-transport.png"> <p style='font-size: 10px;'>©Oliver Steele, <a>https://blog.osteele.com/2008/05/my-git-workflow/</a></p> --- # des questions ? Lien vers le dépôt de cette présentation : https://forgemia.inra.fr/elisemaigne/2021_git/ #### Références - https://perso.liris.cnrs.fr/pierre-antoine.champin/enseignement/intro-git/ - http://rogerdudler.github.io/git-guide/index.fr.html - Doc de la forgemia : https://forgemia.inra.fr/adminforgemia/doc-public/-/wikis/GIT-sous-Windows - branches git en graphviz : https://correl.phoenixinquis.net/2015/07/12/git-graphs.html - Des jolies animations : https://www.miximum.fr/blog/enfin-comprendre-git/ - Comprendre l'index (stage) : https://medium.com/hackernoon/understanding-git-index-4821a0765cf #### Des cours en ligne - [Apprendre à utiliser Git et GitHub - 2020](https://www.pierre-giraud.com/git-github-apprendre-cours/modifier-depot-git/) - [Utiliser GIT avec R, INSEE, 2021](https://linogaliana.gitlab.io/collaboratif/git.html) - [Tutoriel GitLab, 2018](https://github.com/SocialGouv/tutoriel-gitlab) --- name: bonus # Bonus - Différence SVN/Git () #### SVN SVN est un système de contrôle de version **centralisé**. Vous avez un serveur qui contient votre référentiel de code. Vous pouvez en extraire du code sur votre ordinateur local, y apporter des modifications locales, puis les renvoyer dans le référentiel central. Votre copie du code correspond généralement à ce que vous avez extrait et à la dernière version. De nombreuses opérations nécessiteront une connexion réseau au référentiel central. #### Git Git est un système de contrôle de version **décentralisé**. Chaque participant a un clone de l’ensemble du référentiel. Il est utilisé pour suivre les changements dans le code source. La plupart des opérations ne nécessitent pas de connexion réseau, car elles ne travaillent que sur votre clone du référentiel. *Source : https://waytolearnx.com/2019/03/difference-entre-git-et-svn.html* --- name: diff # Regarder les différences entre le local et un autre état ```bash git diff ``` <img src="images/gitdiff.png"> --- name: yml ## Exemple de fichier yml (nom de fichier = .gitlab-ci.yml) .tiny[ ```yml pages: stage: deploy # Je place le nécessaire dans un dossier public/ script: - mkdir public - cp -r presentation/* public artifacts: paths: - public # Je fais tout ça uniquement sur la branche main only: - main ``` ] --- name: yml2 ## Exemple de fichier yml (nom de fichier = .gitlab-ci.yml) .tiny[ ```yml # J'appelle une image docker qui contient R, rmarkdown, ... https://hub.docker.com/r/rocker/verse image: rocker/verse:4.0.0 # J'installe les packages qui ne sont pas dans l'image rocker/verse before_script: - Rscript -e "install.packages('showtext')" - Rscript -e "install.packages('DiagrammeR')" - Rscript -e "install.packages('xaringanthemer')" - Rscript -e "install.packages('widgetframe')" pages: stage: deploy # Je compile mon document et je place le nécessaire dans un dossier public/ script: - Rscript -e "rmarkdown::render('presentation.Rmd', output_file = 'index.html')" - mkdir public - cp index.html xaringan-themer.css mycss.css public/ - cp -r images/ libs/ public/ artifacts: paths: - public # Je fais tout ça uniquement sur la branche main only: - main interruptible: true ``` ]