\documentclass[usepdftitle=false]{beamer} \usepackage[frenchb]{babel} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{graphicx} \usepackage{datetime} \usepackage{eurosym} \usepackage[]{url} \usepackage[babel=true]{csquotes} \usepackage{listings} \usepackage{fancyvrb} \usepackage{xcolor} \hypersetup{ pdfauthor={Thibaud Duhautbout - Rémy Huet}, pdftitle={Formation Picaosft : La gestion de version avec Git}, pdfsubject={Formation niveau 2 : concepts avancés}, pdfkeywords={git, gestion de version, VCS}, pdfproducer={Latex}, } \beamertemplatenavigationsymbolsempty \setbeamercolor{orangebox}{bg=orange,fg=black} \setbeamercolor{terminal}{bg=darkgray,fg=white} \definecolor{myGreen}{HTML}{0f8e1d} \newdateformat{nombres}{\THEDAY-\THEMONTH-\THEYEAR} \def\seplength{.3\topsep} % Dans le cas d'une compilation pour la présentation, on active les % pauses dans les slides (inutiles pour la version support à diffuser) \newcommand{\Pause}{% \ifdef{\Release} {\pause} {} } \title[Formation Git\_v2]{Formation Picasoft : La gestion de version avec Git (niveau 2)} \titlegraphic{\includegraphics[scale=.1]{picasoft_logo.png}} \author[T. Duhautbout - R. Huet]{Thibaud {\sc Duhautbout} \\ Rémy {\sc Huet}} \institute[Picasoft]{Association Picasoft} \date[24/10/2018]{Mercredi 24 octobre 2018} \usetheme{AnnArbor} \usecolortheme{crane} \fvset{fontsize=\tiny,commandchars=\\\{\}} \AtBeginSection[] { \begin{frame} \tableofcontents[currentsection, hideothersubsections] \end{frame} } \begin{document} \begin{frame} \titlepage \end{frame} \section{Petits rappels} \begin{frame}[fragile] \frametitle{Gestion de version de base} \framesubtitle{Valider et vérifier ses changements} \begin{block}{Init, status, add, commit} \begin{itemize} \item \verb+git init+ : création d'un dépôt; \item \verb+git status+ : visualisation du statut du dépôt; \item \verb+git add+ : ajout de fichiers dans la zone de validation; \item \verb+git commit -m ``message''+ : validation des changements. \end{itemize} \end{block} \begin{block}{Diff, log} \begin{itemize} \item \verb+git log+ : afficher l'historique des commits; \item \verb+git diff+ : changements par rapport à la zone de validation; \item \verb+git diff + : changements depuis un commit; \item \verb+git diff + : changements entre deux commits. \end{itemize} \end{block} \end{frame} \begin{frame}[fragile] \frametitle{Gestion de version de base} \framesubtitle{Mettre de côté ou annuler ses changements} \begin{block}{Stash} \begin{itemize} \item \verb+git stash+ : mettre ses changements sur la pile stash; \item \verb+git stash pop+ : récupérer le dernier stash. \end{itemize} \end{block} \begin{block}{Checkout} \begin{itemize} \item \verb+git checkout + : remettre son dépôt dans un état antérieur (de manière provisoire et réversible); \item \verb+git checkout master+ : revenir au dernier commit; \item \verb+git checkout -- + : remettre le fichier/dossier dans l'état du dernier commit (irréversible). \end{itemize} \end{block} \end{frame} \begin{frame}[fragile] \frametitle{Gestion de version de base} \framesubtitle{Les remotes} \begin{block}{Clone, pull, push} \begin{itemize} \item Utilisation du GitLab de l'UTC (\url{https://gitlab.utc.fr}); \item \verb+git clone + : récupération d'un dépôt depuis le remote; \item \verb+git pull+ : récupérer des cangements depuis le dépôt en ligne; \item \verb+git push+ : pousser des changements sur le dépôt en ligne. \end{itemize} \end{block} \end{frame} \begin{frame} \frametitle{Avant de commencer} Des questions ? \end{frame} \section{Amélioration de son espace de travail} \subsection{Génération de clé ssh} \begin{frame} \frametitle{Générer sa paire de clés} \framesubtitle{Utilité et théorie} \begin{block}{Pourquoi ?} Une sorte de \enquote{mot de passe} stocké sur la machine, qui permet de s'authentifier à un serveur ssh. Dans notre cas, permettra de se passer de login et de mot de passe pour l'authentification à la remote. \end{block} \begin{block}{Comment ça marche ?} \begin{itemize} \item Algorithme RSA; \item Une clé publique destinée à être partagée au monde; \item Une clé privée permettant de certifier que l'on est la personne à qui appartient la clé publique. \end{itemize} \end{block} \end{frame} \begin{frame}[fragile] \frametitle{Générer sa paire de clés} \framesubtitle{Comment faire ?} \begin{beamercolorbox}[rounded=true,shadow=true]{terminal} \begin{Verbatim} $ ssh-keygen -b 4096 \Pause Generating public/private rsa key pair. Enter file in which to save the key (/home/remy/.ssh/id_rsa):\Pause Enter passphrase (empty for no passphrase):\Pause Enter same passphrase again:\Pause The key fingerprint is: SHA256:B8IbOIXrMqGEgYOKhqnbelKKbzN35XqlVK/IfUnGQJQ remy@remy-HP-ZBook-15-G2 The key's randomart image is: +---[RSA 4096]----+ |o .. ... | |= .+ E | |=+ o.+ .. | |*o. .. + .o | |+. o . S..+ | |o + . o.. = | |.= o = = + . | |= * . . * o o | |.*.+ ..o . | +----[SHA256]-----+ \end{Verbatim} \end{beamercolorbox} \end{frame} \begin{frame}[fragile] \frametitle{Utilisation} \begin{itemize} \item Ajout de la clé publique sur GitLab \end{itemize} Pour indiquer à git qu'il faut utilisaer \verb+ssh+ plutôt que \verb+https+ pour se connecter au remote, on utilise une uri différente lors du \verb+clone+ Par exemple, pour récupérer le repo de la formation niveau 1, on tapera \verb+git clone git@gitlab.utc.fr:picasoft/formations/A18/git-v1+ \end{frame} \section{Les branches} \subsection{Principe} \begin{frame}{Principe} \begin{block}{} \enquote{Git permet de maintenir plusieurs versions différentes en parallèle} \begin{flushright} \textit{Nous, il y a deux semaines} \end{flushright} \end{block} \Pause Concrètement, tous les commits ne sont pas nécessairement sur la même \textbf{branche} de l'arbre. \begin{center} \includegraphics[width=.7\linewidth]{./imgs/branches.eps} \end{center} \textit{Le sens des flèches n'est pas chronologique ! Chaque commit pointe vers son père.} \end{frame} \begin{frame}{Création d'une divergence -- cas 1} \begin{center} \includegraphics[width=.4\linewidth]{./imgs/divergence.png} \end{center} \begin{block}{Analyse} \begin{itemize} \item C2 et C3 ont tous les deux C1 comme père; \item C2 et C3 introduisent des modifications différentes après C1; \item ici, C2 et C3 sont sur \textbf{deux branches différentes de C1}; \end{itemize} \end{block} \end{frame} \begin{frame}{Création d'une divergence -- cas 2} \begin{center} \includegraphics[width=.3\linewidth]{./imgs/divergence_2.png} \end{center} \begin{block}{Analyse} \begin{itemize} \item C4 et C5 ont tous les deux C3 comme père; \item C4 et C5 introduisent des modifications différentes après C3; \item C4 est sur une branche \textbf{différente de C3}; \item C5 est sur \textbf{la même branche que C3}. \end{itemize} \end{block} \end{frame} \begin{frame}{Création d'une divergence} \begin{block}{} \centering \enquote{Mais pourquoi est-ce qu'on fait ça ?} \end{block} \Pause \begin{itemize} \item pour isoler les travaux en cours \item pour enregistrer des versions spécifiques \end{itemize} \Pause \begin{block}{} \centering \enquote{Et c'est quoi la différence entre le cas 1 et le cas 2 ?} \end{block} \Pause En théorie, pas grand chose à part la couleur : \begin{itemize} \item c'est une divergence dans les deux cas; \item dans le cas 1, il est encore possible de faire un commit sur la branche jaune après C1. \end{itemize} En pratique avec git : \begin{itemize} \item ça dépend des modifications apportées et du sens que vous donnez à vos branches. \end{itemize} \end{frame} \begin{frame}{Création d'une divergence -- illustration} \begin{center} \includegraphics[width=.6\linewidth]{./imgs/branches.eps} \end{center} \begin{block}{Exemple} \begin{itemize} \item C0 et C1 sont sur une branche \enquote{stable} : tout est relu \Pause \item C2 introduit des modifications non relues à un endroit \item C3 introduit des modifications non relues à un autre endroit \Pause \item C4 avance à partir de C3 mais c'est incomplet, donc nouvelle branche \Pause \item C5 poursuit les modifications de C3 \item C6 poursuit les modifications de C4 \end{itemize} \end{block} \end{frame} \begin{frame}{Fusion !} \begin{center} \includegraphics[width=.6\linewidth]{./imgs/branches.eps} \end{center} \begin{block}{} \centering \enquote{Attends un peu, et C7 il fait quoi ? Et pourquoi il a deux pères ?} \end{block} \Pause \begin{itemize} \item C7 est un commit un peu spécial : c'est un \textbf{commit de fusion}; \item Objectif : intégrer les modifications de la branche bleue dans la branche verte; \item Il a bien \textbf{deux} pères (c'est la seule situation où ça arrive); \item \textbf{Attention !} Si C5 et C6 portent des modifications qui se recouvrent, la fusion va créer des \textbf{conflits} qu'il faudra régler avant de créer C7. \end{itemize} \end{frame} \subsection{Application avec git} \subsection{Fusion de deux branches} \subsection{Gestion des conflits} \begin{frame} \frametitle{Les conflits} \framesubtitle{C'est quoi un conflit ?} {\bf Définition :} On parle de conflit lorsque deux personnes on modifié les mêmes lignes d'un fichier {\bf en parallèle} et que git ne peut donc pas savoir quelle version conserver lors d'une fusion. {\bf Concrètement,} on peut avoir un conflit : \begin{itemize} \item Lors d'un merge; \item Lorsque l'on fait un commit sans être à jour avec la branche distante (ce qui impliquera un merge lors du prochain pull); \item Lors d'un rebase; \item Quand on réapplique des modofications qui vaient été mises de côté via un stash. \end{itemize} \end{frame} \begingroup \tiny% \begin{frame} \frametitle{Les conflits} \framesubtitle{Exemple de situation conflictuelle} \begin{center} \includegraphics[height=.2\paperheight]{imgs/conflit.png} \end{center} \begin{block}{Exemple :} À partir du commit C3 : \begin{itemize} \item Alice crée une nouvelle branche sur laquelle elle effectue les commits C4 et C6 ; \item Pendant ce temps, Bob effectue le commit C5 sur la branche verte il modifie des lignes que Alice modifie également lors de C4 et C6 ; \item Alice veut fusionner sa branche dans la branche verte. Malheureusement, comme Bob a modifié les mêmes lignes qu'elle, git ne sait pas quelles sont les modifications à garder; \item Le commit C7 correspond donc à un commit de merge lors duquel Alice règle les conflits entre sa branche et celle de Bob. \end{itemize} \end{block} \end{frame} \endgroup \begin{frame}[fragile] \frametitle{Comment gérer un conflit ?} \framesubtitle{Comment se présente un conflit ?} \begin{beamercolorbox}[rounded=true, shadow=true]{terminal} \begin{Verbatim} $ git merge develop \Pause Fusion automatique de fichier.txt CONFLIT (contenu) : Conflit de fusion dans fichier.txt La fusion automatique a échoué ; réglez les conflits et validez le résultat.\Pause $ git status \Pause Sur la branche master Vous avez des chemins non fusionnés. (réglez les conflits puis lancez "git commit") (utilisez "git merge --abort" pour annuler la fusion) Chemins non fusionnés : (utilisez "git add ..." pour marquer comme résolu) \textcolor{red}{modifié des deux côtés : fichier.txt} aucune modification n'a été ajoutée à la validation (utilisez "git add" ou "git commit -a") \Pause $ cat fichier.txt \ldots <<<<<<< HEAD Lorem ipsum dolor sit amet, consectetur adipiscing elit. ======= Integer nec porta orci, non egestas odio. >>>>>>> develop \ldots \end{Verbatim} \end{beamercolorbox} \end{frame} \begin{frame}[fragile] \frametitle{Comment gérer un conflit ?} {\small Pour résoudre le conflit, on réécrit les zones signalées par \verb+<<<<<<<+ et \verb+>>>>>>+ puis on commit. On devrait obtenir quelque-chose de similaire à :} \begin{beamercolorbox}[rounded=true, shadow=true]{terminal} \begin{Verbatim} $ git log --graph --decorate * \textcolor{yellow}{commit c2ad233444831dc5f1c5cab906c6331ef21255d6 (}{\bf \textcolor{cyan}{HEAD ->}} \textcolor{green}{master}\textcolor{yellow}{)} \textcolor{red}{|}\textcolor{myGreen}{|} Merge: 828081a 80506c2 \textcolor{red}{|} \textcolor{myGreen}{|} Author: huetremy \textcolor{red}{|} \textcolor{myGreen}{|} Date: Sun Oct 14 19:24:10 2018 +0200 \textcolor{red}{|} \textcolor{myGreen}{|} \textcolor{red}{|} \textcolor{myGreen}{|} Merge branch 'develop' \textcolor{red}{|} \textcolor{myGreen}{|} \textcolor{red}{|} * \textcolor{yellow}{commit 80506c20684f17b4f953c905cdd5016b3ec9ae0f (}\textcolor{green}{develop}\textcolor{yellow}{)} \textcolor{red}{|} \textcolor{myGreen}{|} Author: huetremy \textcolor{red}{|} \textcolor{myGreen}{|} Date: Sun Oct 14 19:17:18 2018 +0200 \textcolor{red}{|} \textcolor{myGreen}{|} \textcolor{red}{|} \textcolor{myGreen}{|} Autre changement \textcolor{red}{|} \textcolor{myGreen}{|} * \textcolor{myGreen}{|} \textcolor{yellow}{commit 828081a463eadbfd4537b152a709d981a19a7bad} \textcolor{myGreen}{|/} Author: huetremy \textcolor{myGreen}{|} Date: Sun Oct 14 19:15:57 2018 +0200 \textcolor{myGreen}{|} \textcolor{myGreen}{|} Changement ligne \textcolor{myGreen}{|} * \textcolor{yellow}{commit 3cc9dea071fe166309fd8a2c239469c5a71d8da0} Author: huetremy Date: Sun Oct 14 19:14:13 2018 +0200 Ajout fichier \end{Verbatim} \end{beamercolorbox} \end{frame} \subsection{Travail collaboratif} \section{Introduction à git flow} \begin{frame}[fragile] \frametitle{Pourquoi Git flow ?} Problématique de collaboration sur des gros projets : \begin{itemize} \item Avoir une branche \verb+master+ stable à tout moment; \item Créer une branche par nouvelle fonctionnalité : \begin{itemize} \item Pour une organisation plus claire; \item Pour développer plusieurs fonctionnalités en parallèle. \end{itemize} \item Avoir une branche de développement pour merge les fonctionnalités finies, mais qui n'est pas une branche stable. \end{itemize} \end{frame} \begin{frame} \frametitle{Comment ça fonctionne ?} \framesubtitle{Les branches master et develop} \begin{block}{La branche master} Il s'agit d'une branche stable. À tout moment son commit le plus récent correspond à une version fonctionnelle du projet. \end{block} \begin{block}{La branche develop} C'est la branche de travail courante. C'est sur celle-ci qu'on ajoute au fur et à mesure les fonctionnalités, et que l'on mergera dans master pour effectuer une release \end{block} \end{frame} \begin{frame} \frametitle{Comment ça fonctionne ?} \framesubtitle{Feature, bugfix, release et hotfix} Ce sont des branches avec des utilités bien définies : \begin{block}{feature} Une fonctionnalité particulière, qui sera merge dans develop quand elle sera finie \end{block} \begin{block}{bugfix} Résolution d'un bug {\bf qui n'existe que sur dévelop}. Sera merge dans develop \end{block} \begin{block}{release} Permet de faire des modifications sur le projet avant la sortie d'une release. Merge dans master et dans develop (crée un tag sur master) \end{block} \end{frame} \begin{frame} \frametitle{Comment ça fonctionne ?} \framesubtitle{Hotfix} \begin{block}{hotfix} Pour résoudre un bug qui est présent sur une version \enquote{stable} (donc dans master). Sera merge dans develop {\bf et} dans master (crée un tag sur master). \end{block} \begin{center} \includegraphics[height=.5\paperheight]{imgs/git_flow.png} \end{center} \end{frame} \end{document}