\documentclass[10pt]{beamer} \usepackage{ucs} \usepackage[utf8]{inputenc} \usepackage[french]{babel} \usepackage[T1]{fontenc} \usepackage{graphicx} \title{Git c'est la vie} \subtitle{Un cours sur cet outil magique qui s'appelle git} \author{Francesco Bariatti} % Put table of contents at the beginning of each section \AtBeginSection[] { \begin{frame}[noframenumbering]{} \tableofcontents[currentsection] \end{frame} } \usetheme{CambridgeUS} \usecolortheme{beaver} \begin{document} \frame{\titlepage} \begin{frame} \frametitle{Plan} \tableofcontents \end{frame} \section{Prérequis} \begin{frame}[fragile] \frametitle{Prerequis} Prérequis pour suivre ce cours: \begin{itemize} \item Savoir lire la signature d'une commande \verb#command -a [-b] [-c | -d] --long-arg PARAM1 PARAMS2...# \item Savoir lire des messages affichés dans la console. Git affiche plein de messages utiles, il faut les lire. \end{itemize} \end{frame} \section{Présentation de git} \begin{frame} \frametitle{C'est quoi git} \begin{columns}[c] \column{0.5\textwidth} \begin{block}{} Git est un logiciel de versioning. \end{block} \begin{itemize} \item Crée par notre modèle spirituel, Linus Torvalds en 2005. \item Le logiciel de versioning utilisé pour le noyau Linux est devenu propriétaire, donc il en a développé un autre. \end{itemize} \column{0.5\textwidth} \begin{center} \includegraphics[scale=0.2]{img/linus} \end{center} \end{columns} \end{frame} \begin{frame} \frametitle{Ça permet de faire quoi} \begin{itemize} \item Ne pas perdre son travail \item Pouvoir inspecter des versions spécifiques de son travail \item Travailler à plusieurs \item Pouvoir donner la faute d'un bug à un collègue (on sait qui a codé quoi) \end{itemize} \vspace{2\baselineskip} \begin{itemize} \item Git n'est pas un logiciel qui tourne en permanence: chaque commande est un petit processus. \item Tout est enregistré dans des fichiers \begin{itemize} \item Possible d'interrompre le travail à tout moment \end{itemize} \end{itemize} \begin{alertblock}{} Git fonctionne très mal avec les fichiers binaires \end{alertblock} \end{frame} \section{Le commit} \begin{frame} \begin{block}{} Le commit est l'entité de base de git. \end{block} Un commit c'est: \begin{itemize} \item Un ensemble de changements (sur un ou plusieurs fichiers) \item Une date \item Un auteur \item \textbf{Un message}: il peut être sur plusieurs lignes! \item \textbf{Un pointeur vers sont parent} \item \textbf{Un hash unique} basé sur tout ça (plus ou moins). \end{itemize} \begin{alertblock}{} Les commit doivent raconter une histoire! \end{alertblock} \end{frame} \begin{frame} \frametitle{Un historique git} \begin{columns}[c] \column{0.3\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/gitrepo} \end{center} \column{0.7\textwidth} \begin{itemize} \item Historique git: suite de commits (+ pointeur sur dernier). \item Un fichier existe seulement comme suite de modifications. \item Un commit non pointé est un commit perdu. \end{itemize} \end{columns} \end{frame} \begin{frame}[fragile] \frametitle{Des commandes!} \begin{itemize} \item Création d'un projet: \verb|git init DOSSIER| ou \verb|git clone URL [DOSSIER]| \item Visualisation de l'état (est-ce qu'il y a eu des modifications?): \verb|git status| \item Visualisation des modifications: \verb|git diff| \item Ajouter des modifications au prochain commit: \verb|git add FICHIERS...| \item Créer un commit: \verb|git commit| \item Voir l'historique: \verb|git log| \item Voir le log en plus joli: \verb|git log --all --graph --decorate --oneline| \end{itemize} \end{frame} \section{Les branches} \subsection{Le concept des branches} \begin{frame} \frametitle{Ça sert à quoi?} \begin{itemize} \item Travailler à plusieurs. \item Faire plusieurs choses au même temps (nouvelle fonctionnalité, correction de bugs, ...). \item Essayer des nouvelles choses en parallèle sans impacter le projet: modifications indépendantes sur une même base. \end{itemize} \vspace{2\baselineskip} \begin{itemize} \item Très facile de basculer de l'une à l'autre: git modifie les fichiers automatiquement. \end{itemize} \end{frame} \begin{frame} \frametitle{C'est quoi?} \begin{columns}[c] \column{0.4\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/branches} \end{center} \column{0.6\textwidth} \begin{itemize} \item Branche: pointeur sur un commit \end{itemize} \vspace{\baselineskip} \begin{itemize} \item Une histoire qui diverge à partir d'un certain commit \item En se positionnant sur un pointeur ou sur un autre on voit des choses différentes \end{itemize} \end{columns} \end{frame} \subsection{Le merge} \begin{frame} \frametitle{Le merge} \begin{columns}[c] \column{0.5\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/merge} \end{center} \column{0.5\textwidth} \begin{itemize} \item Intègre les changements d'une branche dans une autre \item Création d'un commit de merge: commit spécial avec deux parents \item À partir de la branche de destination (Branche1 dans l'exemple) il est possible de voir l'historique des deux branches. \item Git fusionne intelligemment les modifications des deux branches \end{itemize} \end{columns} \end{frame} \begin{frame} \frametitle{Les conflits de merge :(} Parfois impossible de fusionner automatiquement: si les deux branches ont modifié le même bout de code. \begin{block}{} Le commit de merge peut introduire des modifications: utilisé pour résoudre les conflits \end{block} \begin{itemize} \item Git affiche un message d'erreur en cas de conflit \item Les conflits sont clairement délimités dans les fichiers à l'aide de chevrons \item Git présente les deux versions du bout de code et demande à l'humain de choisir la version finale (en modifiant le code et supprimant les chevrons) \item Il est aussi possible d'abandonner le merge \end{itemize} \begin{block}{} En faisant des petits commits, il est plus simple de repérer quelle modification a introduit le conflit. \end{block} \end{frame} \begin{frame}{Le merge ``fast-forward''} \begin{columns} \column{0.5\textwidth} \begin{center} \includegraphics[width=\textwidth]{img/fast-forward} \end{center} \column{0.5\textwidth} \begin{itemize} \item Quand il n'y a pas de modifications à fusionner \item Le pointeur de branche est simplement modifié \end{itemize} \end{columns} \end{frame} \subsection*{Les commandes des branches} \begin{frame}[fragile] \frametitle{Les commandes des branches} \begin{itemize} \item Créer une branche avec comme base le commit courant: \verb|git branch NAME| \item Bouger entre les branches: \verb|git checkout BRANCH| \item Fusionner une branche: \verb|git merge ORIGINE [DESTINATION]| \item En cas de conflit: \begin{itemize} \item Modifier les fichiers à la main \item \verb|git add FICHIERS...| \item \verb|git commit| ou \verb|git merge --continue| \end{itemize} \item Il est aussi possible d'abandonner la fusion pendant un conflit: \verb|git merge --abort| \end{itemize} \end{frame} \section{Dépôts distants (remotes)} \subsection{Explication} \begin{frame} \frametitle{Les dépôts distants} Chaque développeur a toujours une \textit{copie intégrale} du projet. Il est possible d'avoir une copie du projet sur un serveur pour mettre en commun le travail. \begin{block}{} La copie d'un branche hébergée sur le serveur n'est qu'une branche. Elle peut être inspectée comme toute branche locale (il faut la récupérer avant). \end{block} \end{frame} \begin{frame} \begin{columns}[T] \column{0.5\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/remotes_non_diverging} \end{center} \column{0.5\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/remotes_diverging} \end{center} \end{columns} \end{frame} \begin{frame} \frametitle{Historique commun} Sur git il est possible de modifier l'historique (réorganiser les commits, les modifier, ...). Même si on ne verra pas comment faire, il faut toujours retenir: \begin{alertblock}{} Il ne faut jamais modifier l'historique commun!!! \end{alertblock} Tout ce qui a été poussé sur un dépôt distant est commun. Il ne faut modifier rien qui puisse être atteint à partir d'un commit présent sur le dépôt commun. \end{frame} \subsection{Les commandes} \begin{frame}[fragile] \frametitle{Les commande des remotes} \begin{itemize} \item Récupère les modifications de la branche remote sans les intégrer à la branche courante (= met à jour les branches \verb|origin/*|): \verb|git fetch| \item Récupère les modifications de la branche remote et les ajoute dans la branche courante: \verb#git pull [ --merge | --rebase ]# \item Pousse les modifications de la branche courante sur le remote: \verb|git push|. \begin{itemize} \item Dans le cas que la branche remote n'existe pas (elle va être crée): \verb|git push -u origin NAME| \end{itemize} \end{itemize} \end{frame} \subsection{Les techniques de pull} \begin{frame} \frametitle{Pull merge (default)} \begin{columns}[T] \column{0.5\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/pull_before} \end{center} \column{0.5\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/pull_merge} \end{center} \end{columns} \end{frame} \begin{frame} \frametitle{Pull rebase} \begin{columns}[T] \column{0.5\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/pull_before} \end{center} \column{0.5\textwidth} \begin{center} \includegraphics[height=0.7\textheight]{img/pull_rebase} \end{center} \end{columns} \end{frame} \section{Pointeurs avancés} \begin{frame}[fragile] \frametitle{Le pointeur HEAD} \begin{itemize} \item HEAD est un pointeur sur la situation ``courante'' des fichiers. \item Il pointe normalement sur la branche courante \item \verb|git checkout COMMIT_HASH| permet de bouger HEAD à un autre point de l'histoire: les fichiers auront alors le contenu qu'ils avaient à ce moment là. \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Le soft reset} \verb|git reset COMMIT_HASH| permet de bouger la tête de la branche sur un commit particulier. Il n'y a plus rien qui pointe sur les commits plus récents, \textbf{ils sont alors oubliés}. Les fichiers ne sont par contre pas modifiés. \end{frame} \begin{frame}[fragile] \frametitle{Le hard reset} \verb|git reset --hard COMMIT_HASH| permet de bouger la tête de la branche sur un commit particulier, \textbf{en écrasant toutes les modifications faites depuis}. \begin{block}{} \verb|git reset --hard HEAD| supprime toutes les modifications faites depuis le dernier commit (donc juste les modifications pas enregistrées dans un commit). \end{block} \end{frame} \frame{\titlepage} \end{document}