From e0fff70aec7a11ad6d7a3f1d22bd52dad5b7a0bf Mon Sep 17 00:00:00 2001 From: Robert Alessi Date: Wed, 3 Oct 2018 15:47:28 +0200 Subject: 02-git.tex: introduction --- _preamble_bbl.tex | 5 +- bibliography.bib | 11 ++ fichiers/01-ligne-de-commande.tex | 2 +- fichiers/02-git.tex | 357 +++++++++++++++++++++++++++++++++++++- 4 files changed, 367 insertions(+), 8 deletions(-) diff --git a/_preamble_bbl.tex b/_preamble_bbl.tex index d7be120..383f396 100644 --- a/_preamble_bbl.tex +++ b/_preamble_bbl.tex @@ -1,7 +1,8 @@ \usepackage[style=footnote-dw, xref=true, loccittracker, opcittracker, autopunct=false, ibidemfont=italic, idemfont=italic, -idembibformat=dash, nopublisher=false, annotation=true, pageref=true, -journalnumber=date, acronyms=true]{biblatex} +citeauthorname=firstfull, idembibformat=dash, nopublisher=false, +annotation=true, pageref=true, journalnumber=date, +acronyms=true]{biblatex} \DefineBibliographyExtras{french}{% \renewcommand{\mkbibnamefamily}[1]{#1}% diff --git a/bibliography.bib b/bibliography.bib index ec8c1eb..ff4e830 100644 --- a/bibliography.bib +++ b/bibliography.bib @@ -4,3 +4,14 @@ year = 1983, url = {http://www.literateprogramming.com/knuthweb.pdf}} +@Book{Chacon.Straub2018, + author = {Chacon, Scott and Straub, Ben}, + title = {Pro Git}, + date = {2018-08-27}, + subtitle = {Tout ce que vous devez savoir sur Git}, + edition = 2, + publisher = {Apress}, + url = {https://www.git-scm.com/book/fr/v2}, + addendum = {v2.1.21 disponible en version .pdf}, + urldate = {2018-10-03}} + diff --git a/fichiers/01-ligne-de-commande.tex b/fichiers/01-ligne-de-commande.tex index 66cfdce..edc3765 100644 --- a/fichiers/01-ligne-de-commande.tex +++ b/fichiers/01-ligne-de-commande.tex @@ -606,7 +606,7 @@ possibles: \verb+photos_de_vacances.zip+ \end{quoting} -\paragraph{Fichiers cachés} +\paragraph{\hypertarget{lnk_hidden}{Fichiers cachés}} Tout fichier dont le nom commence par un point (\mintinline{text}|.|) est considéré comme un fichier caché. Le plus souvent, les fichiers cachés contiennent des paramètres de configuration. La commande diff --git a/fichiers/02-git.tex b/fichiers/02-git.tex index 87767ab..a314c80 100644 --- a/fichiers/02-git.tex +++ b/fichiers/02-git.tex @@ -1,5 +1,7 @@ \input{../_preamble} -%\input{../_preamble_bbl} +\input{../_preamble_bbl} +% \usepackage{biblatex} +% \addbibresource{../bibliography} \usepackage{menukeys} \title{Git} \usepackage{float} @@ -32,13 +34,358 @@ \renewcommand{\contentsname}{Sommaire} \tableofcontents -\listoflistings +% \listoflistings -\needspace{3\baselineskip} -\listoftables +% \needspace{3\baselineskip} +% \listoftables \chapter{Introduction} \label{cha:introduction} +\paragraph{Avertissement} +Dans les pages qui suivent, on cherche à donner au lecteur quelques +éléments sur la notion de \emph{système de contrôle de version} en +général et sur \emph{Git} en particulier. L'ouvrage de référence, +\citetitle{Chacon.Straub2018}, traduit en français, est disponible en +ligne\autocite{Chacon.Straub2018}. -\end{document} \ No newline at end of file +\section{Les systèmes de contrôle de version} +\label{sec:vers-contr-syst} +Les \enquote{systèmes de contrôle de version}, en anglais +\emph{version control systems} (VCS), sont des logiciels qui +permettent de suivre toutes les modifications des fichiers et des +répertoires qui se trouvent dans un répertoire donné. À partir du +moment où l'on décide de suivre le contenu d'un répertoire, on peut +retrouver l'état qui était le sien dans le passé à tout moment. + +Supposons que l'on ait quelque part modifié un paragraphe dans un +texte, ajouté ou retranché des lignes: le système de contrôle de +version permet alors de retrouver la chronologie de toutes les +modifications et de les afficher clairement, l'une après l'autre. On a +ainsi l'assurance de ne jamais rien perdre de son travail. + +Le contrôle de version permet également de travailler en même temps +sur différentes \emph{branches}. On distingue ainsi la \emph{branche + principale} de toutes les \emph{branches secondaires} que l'on peut +ouvrir à tout moment. Prenons un exemple: à un moment donné, on +souhaite revenir sur une page complexe que l'on a rédigée et y +apporter des modifications. Mais pour autant, on n'approuve pas encore +ces modifications et on voudrait ne rien perdre de la version +originale. On ouvre alors une \emph{branche secondaire} dans laquelle +on modifie à souhait la page. Durant tout le travail sur la branche +secondaire, le travail enregistré dans la branche principale n'est pas +altéré. Une fois terminé le travail sur la branche secondaire, on peut +l'abandonner ou bien, si le résultat est satisfaisant, le +conserver. Dans ce cas, on demande au système de contrôle de version +de \emph{fusionner} dans la branche principale la branche secondaire +sur laquelle on a travaillé. Puis on continue le travail dans la +branche principale, après avoir effacé la branche secondaire, tout en +sachant qu'à tout moment, toutes les étapes de ces modifications +peuvent être retrouvées. Bien entendu, le système permet d'ouvrir +simultanément autant de branches qu'on le souhaite. + +\subsection{Différents concepts, différentes approches} +\label{sec:diff-conc-diff} +On distingue trois types de systèmes de contrôle de version: +\begin{enumerate} +\item \textbf{Les systèmes locaux} qui enregistrent les modifications + dans une base de données. Quand un fichier est modifié, ces systèmes + enregistrent non pas les deux versions du fichier modifié, mais un + seul fichier, en plus du fichier initial, dans lequel sont + simplement notées les \emph{différences} de l'un à l'autre. +\item \textbf{Les systèmes centralisés} qui font la même chose que les + systèmes locaux, mais dans lesquels la base de données se trouve sur + un serveur. L'avantage est que l'on peut alors organiser un travail + de groupe. Mais l'inconvénient est que si le serveur est en panne, + alors la base de données est inaccessible et personne ne peut + travailler. +\item \textbf{Les systèmes distribués} dans lesquels les différents + utilisateurs travaillent non pas sur des fichiers reconstitués à + l'aide de la somme des modifications enregistrées sur un serveur, + mais sur une version autonome et dupliquée de tous les fichiers qui + sont sur le serveur. Chacun travaille sur ses fichiers, même hors + réseau. Puis une fois le travail terminé, on envoie sur le serveur + un nouvel état de la base de données que les autres peuvent + synchroniser à tout moment. +\end{enumerate} + +Git est un système de contrôle de version \emph{distribué}. Par +rapport à d'autres systèmes de la même catégorie, il offre un avantage +considérable: celui de travailler non pas sur les \emph{différences} +entre les modifications des fichiers, mais sur des \emph{instantanés} +complets. Prenons un exemple. Soit le fichier suivant +(\verb|recherche.txt|):\label{ref:recherche} +\begin{minted}[linenos]{text} +PREMIÈRE PARTIE +=============== + +COMBRAY +------- + +I + +Longtemps, je me suis couché très tôt. Parfois, à peine ma +bougie éteinte, mes yeux se fermaient si vite que j'avais juste le +temps de me dire: «Je m'endors.» +\end{minted} + +Puis l'auteur se ravise et écrit: +\begin{minted}[linenos]{text} +PREMIÈRE PARTIE +=============== + +COMBRAY +------- + +I + +Longtemps, je me suis couché de bonne heure. Parfois, à peine ma +bougie éteinte, mes yeux se fermaient si vite que je n'avais pas le +temps de me dire: «Je m'endors.» +\end{minted} + +Si l'on demande maintenant à un système informatique d'analyser les +différences entre les deux états de \verb|recherche.txt|, il pourra +produire un résultat comparable à celui-ci: + +\label{ref:diff} +\begin{minted}[linenos,escapeinside=||]{text} +--- recherche.txt 2018-10-03 12:35:05.848903296 +0200 ++++ recherche.txt 2018-10-03 12:31:04.292356175 +0200 +|\textcolor{Blue}{@@ -6,6 +6,6 @@}| + + I +|\textcolor{Red}{-Longtemps, je me suis couché très tôt. Parfois, à peine ma}| +|\textcolor{Red}{-bougie éteinte, mes yeux se fermaient si vite que j'avais juste le}| +|\textcolor{Green}{+Longtemps, je me suis couché de bonne heure. Parfois, à peine ma}| +|\textcolor{Green}{+bougie éteinte, mes yeux se fermaient si vite que je n'avais pas le}| + temps de me dire: «Je m'endors.» +\end{minted} + +\paragraph{Commentaire} +La ligne~3 du rapport ci-dessus permet de comprendre que les +modifications n'interviennent pas avant la ligne~6 du fichier original +\verb|recherche.txt|. Ensuite, nous trouvons les modifications, +entourées de \emph{deux lignes non modifiées qui donnent le contexte}: +ce sont les lignes~5 et 10 du rapport, qui renvoient respectivement +aux lignes~7 et 11 du fichier original. Enfin, nous trouvons les +modifications: dans le rapport, les lignes~6 et 7, rendues en rouge et +précédées du signe $-$, ont été remplacées dans la deuxième version +par les lignes~8 et 9, rendues en vert, et précédées du signe $+$. + +Les systèmes de contrôle de version peuvent donc procéder de deux +manières différentes: +\begin{enumerate} +\item Enregistrer le fichier original seulement, puis tous les + rapports successifs qui donnent les modifications. Ainsi, pour + donner l'état le plus récent d'un fichier, il suffit de prendre + l'original puis de lui appliquer toutes les modifications + successives. +\item Enregistrer toutes les versions successives des fichiers sous la + forme d'\emph{instantanés}. Dans ce cas, les rapports qui + enregistrent les modifications ne sont pas eux-mêmes enregistrés, + mais peuvent toujours être produits à partir de deux instantanés + enregistrés. \textbf{C'est ainsi que procède Git}. +\end{enumerate} + +Bien entendu, quand on travaille sur de nombreux fichiers +simultanément et que, d'une étape à l'autre de son travail, on n'en +modifie que quelques-uns, Git ne prend pas d'instantané des fichiers +non modifiés. Au lieu de faire cela, il enregistre simplement un +\emph{pointeur} vers le dernier instantané du fichier, c'est-à-dire +vers la dernière version modifiée de ce fichier. + +Cette méthode présente de nombreux avantages dont le plus évident +tient à la sécurité. En effet, les systèmes qui enregistrent seulement +les rapports de modifications ne sont plus en mesure de restituer un +fichier donné si l'un de ces rapports est corrompu. Si un chaînon est +manquant, c'est toute la chaîne qui est brisée. Git n'est pas +vulnérable sur ce point. + +\section{Prise en main de Git} +\label{sec:prise-en-main} +\href{https://notabug.org/ralessi/courses/wiki#installation-de-git}{Une +fois Git installé}, il faut l'initialiser en lui indiquant votre nom +et votre email. Pour cela, il suffit d'entrer successivement les deux +lignes suivantes, en veillant à substituer à la fin de chaque ligne +les informations de l'exemple par celles de votre identité. On +veillera également à placer le prénom et le nom, séparé par un espace, +entre guillemets doubles: +\begin{minted}[linenos]{text} +git config --global user.name "John Doe" +git config --global user.email johndoe@example.com +\end{minted} + +Ensuite, \href{./01-ligne-de-commande.pdf}{muni du cours sur la ligne + de commande}, il est possible de créer un répertoire de +travail. Nous allons créer ce répertoire à l'intérieur de notre +répertoire \verb|Documents|, puis nous rendre à l'intérieur de ce +répertoire à l'aide de la commande \verb|cd|: +\begin{minted}{text} +[robert@kiddo ~]$ cd Documents +[robert@kiddo Documents]$ mkdir travail +[robert@kiddo Documents]$ cd travail +[robert@kiddo travail]$ +\end{minted} + +L'étape suivante consiste à demander à Git de suivre le contenu de ce +répertoire: +\begin{minted}{text} +[robert@kiddo travail]$ git init +Dépôt Git vide initialisé dans /home/robert/Documents/travail/.git/ +\end{minted} + +La réponse donnée par Git nous indique où sera maintenue sa base de +données: dans un +\href{./01-ligne-de-commande.pdf#lnk_hidden}{répertoire caché} +\verb|.git| à l'intérieur du répertoire \verb|travail|. + +Commençons donc le travail. À l'aide d'un éditeur de texte, saisissons +le fichier \mintinline{text}|recherche.txt| donné +\vpageref{ref:recherche} et enregistrons-le dans sa première version. +La commande suivante \verb|git status| demande à Git de nous +\emph{fournir un état} du répertoire: +\begin{minted}[linenos,escapeinside=||]{text} +[robert@kiddo travail]$ git status +Sur la branche master + +Validation initiale + +Fichiers non suivis: + (utilisez "git add ..." pour inclure dans ce qui sera validé) + + |\textcolor{Red}{recherche.txt}| + +aucune modification ajoutée à la validation mais des fichiers non suivis sont présents (utilisez "git add" pour les suivre) +\end{minted} + +\paragraph{Commentaire} +Comme on le voit, Git est toujours très explicite. Voici ce qu'il faut +retenir ici de ce rapport: +\begin{enumerate} +\item Ligne~2: par défaut, la \emph{branche principale} est appelée + par Git \verb|master|. +\item Ligne~6 et suivantes: Git donne une simple liste de fichiers + trouvés dans le répertoire et indique qu'on ne lui a pas (encore) + demandé de les \emph{suivre}. C'est un point important qu'il faut + bien comprendre: \emph{Git ne suivra que les fichiers qu'on lui a + demandé d'indexer}. +\item Ligne~7: Git nous donne la commande à utiliser pour indexer le + fichier qui a été trouvé: \mintinline{bash}|git add | +\end{enumerate} + +Exécutons cette commande, puis demandons à Git un nouveau rapport: +\begin{minted}[linenos,escapeinside=||]{text} +[robert@kiddo travail]$ git add recherche.txt +[robert@kiddo travail]$ git status +Sur la branche master + +Validation initiale + +Modifications qui seront validées : + (utilisez "git rm --cached ..." pour désindexer) + + |\textcolor{Green}{nouveau fichier : recherche.txt}| +\end{minted} + +La commande \mintinline{bash}|git add recherche.txt| a eu pour effet +de placer \verb|recherche.txt| \emph{dans la zone d'index de Git} que +l'on appelle \emph{zone de travail} ou \emph{staging area}. + +La dernière opération consiste à enregistrer le fichier dans la base +de données de Git: cela se fait à l'aide de la commande +\mintinline{bash}|git commit|. La syntaxe de cette commande est la +suivante: +\begin{minted}{bash} +git commit -m "" +\end{minted} +où \verb|| est le nom du ou des fichiers à enregistrer, et +\verb|| une petite ligne susceptible de servir +d'aide-mémoire: +\begin{minted}{text} +[robert@kiddo travail]$ git commit recherche.txt -m "version initiale" +[master (commit racine) fa1ec00] version initiale + 1 file changed, 11 insertions(+) + create mode 100644 recherche.txt +\end{minted} + +\paragraph{Poursuite du travail} +Git enregistre tous les \emph{commits} dans un fichier journal, en +anglais \emph{log file} ou plus simplement \emph{log}. Dans les +exemples qui suivent, nous avons inséré dans le fichier +\verb|recherche.txt| donné \vpageref{ref:recherche} les modifications +correspondant à la deuxième version du fichier. + +Comme ce fichier est indexé, la commande \verb|git diff| nous montre +immédiatement quelles sont les différences (v. plus haut +\vpageref{ref:diff}): +\begin{minted}[linenos,escapeinside=||]{text} +[robert@kiddo travail]$ git diff +diff --git a/recherche.txt b/recherche.txt +index 3baf502..f230132 100644 +--- a/recherche.txt ++++ b/recherche.txt +|\textcolor{Blue}{@@ -6,6 +6,6 @@}| COMBRAY + + I + +|\textcolor{Red}{-Longtemps, je me suis couché très tôt. Parfois, à peine ma}| +|\textcolor{Red}{-bougie éteinte, mes yeux se fermaient si vite que j'avais juste le}| +|\textcolor{Green}{+Longtemps, je me suis couché de bonne heure. Parfois, à peine ma}| +|\textcolor{Green}{+bougie éteinte, mes yeux se fermaient si vite que je n'avais pas le}| + temps de me dire: «Je m'endors.» +\end{minted} + +Pour terminer, enregistrons ces modifications: +\begin{minted}{text} +[robert@kiddo travail]$ git commit recherche.txt -m "nouvelle version de l'incipit" +[master 83b6c3e] nouvelle version de l'incipit + 1 file changed, 2 insertions(+), 2 deletions(-) +\end{minted} + +Et demandons à Git de nous fournir un extrait de son journal: +\begin{minted}[linenos,escapeinside=||]{text} +[robert@kiddo travail]$ git log +|\textcolor{Brown}{commit 83b6c3e6dad72116eac5ce7d1ba70968e4e57ebb}| +Author: Robert Alessi +Date: Wed Oct 3 15:05:32 2018 +0200 + + nouvelle version de l'incipit + +|\textcolor{Brown}{commit fa1ec001efdca9c69cc768dc9cf83706bdb6e603}| +Author: Robert Alessi +Date: Wed Oct 3 14:49:10 2018 +0200 + + version initiale +\end{minted} + +Nous voyons aux lignes~2 et 8 qu'à chaque \emph{commit} est associé un +\emph{numéro de registre}, en notation hexadécimale, formé d'une +séquence de~40 caractères allant de \verb|0| à \verb|9| et de \verb|a| +à \verb|f|. + +\subsection{Résumé des commandes} +\label{sec:resume-des-commandes} +\begin{enumerate} +\item \verb|git config --global| $\rightarrow$ paramétrage initial de + Git. +\item \verb|git init| $\rightarrow$ initialisation de Git dans un + nouveau répertoire. +\item \verb|git status| $\rightarrow$ demande à Git un \emph{rapport + d'état}. +\item \verb|git add| $\rightarrow$ indexe des fichiers dans la zone de + travail. Les fichiers indexés sont ceux qui seront suivis par + Git. +\item \verb|git commit -m ""| $\rightarrow$ + enregistre dans la base de données de Git les versions modifiées des + fichiers sous forme d'instantanés. +\item \verb|git diff| $\rightarrow$ montre les différences entre la + version actuelle des fichiers et leur dernière version enregistrée + par % + \verb|git commit|. +\item \verb|git log| $\rightarrow$ affiche le journal de Git. +\end{enumerate} + +\hfill\verb|../.. à suivre| + +\end{document} -- cgit v1.2.3