|
@@ -0,0 +1,391 @@
|
|
|
+\input{../_preamble}
|
|
|
+\input{../_preamble_bbl}
|
|
|
+% \usepackage{biblatex}
|
|
|
+% \addbibresource{../bibliography}
|
|
|
+\usepackage{menukeys}
|
|
|
+\title{Git}
|
|
|
+\usepackage{float}
|
|
|
+\usepackage{dingbat}
|
|
|
+\usepackage[newfloat]{minted}
|
|
|
+\SetupFloatingEnvironment{listing}{listname=Listings}
|
|
|
+\setminted{
|
|
|
+ bgcolor=Lavender,
|
|
|
+ breaklines,
|
|
|
+ breaksymbolright=\small\carriagereturn}
|
|
|
+\setmintedinline{bgcolor=Lavender}
|
|
|
+\usepackage{capt-of}
|
|
|
+\usepackage{soul}
|
|
|
+\makeindex[name=cmds, intoc, title={Liste des commandes et
|
|
|
+ instructions}, options={-s \jobname.ist}]
|
|
|
+
|
|
|
+\NewDocumentCommand{\commande}{s m O{}}{
|
|
|
+ \IfBooleanTF{#1}{\index[cmds]{#2@\texttt{#2}|#3textbf}}
|
|
|
+ {\index[cmds]{#2@\texttt{#2}#3}}
|
|
|
+}
|
|
|
+
|
|
|
+\NewDocumentCommand{\inputfile}{O{} m m O{application/x-sh}}{
|
|
|
+ \marginpar{\attachandlink{scripts/#3}[#4]{Fichier
|
|
|
+ attaché}{\textcolor{blue}{Ouvrir le fichier}}}
|
|
|
+ \inputminted[#1]{#2}{scripts/#3}
|
|
|
+}
|
|
|
+
|
|
|
+\begin{document}
|
|
|
+\maketitle
|
|
|
+\renewcommand{\contentsname}{Sommaire}
|
|
|
+\tableofcontents
|
|
|
+
|
|
|
+% \listoflistings
|
|
|
+
|
|
|
+% \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}.
|
|
|
+
|
|
|
+\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 <fichier>..." 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 <fichier>|
|
|
|
+\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 <fichier>..." 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 <fichier> -m "<message>"
|
|
|
+\end{minted}
|
|
|
+où \verb|<fichier>| est le nom du ou des fichiers à enregistrer, et
|
|
|
+\verb|<message>| 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 <alessi@robertalessi.net>
|
|
|
+Date: Wed Oct 3 15:05:32 2018 +0200
|
|
|
+
|
|
|
+ nouvelle version de l'incipit
|
|
|
+
|
|
|
+|\textcolor{Brown}{commit fa1ec001efdca9c69cc768dc9cf83706bdb6e603}|
|
|
|
+Author: Robert Alessi <alessi@robertalessi.net>
|
|
|
+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 <fichier> -m "<message>"| $\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}
|