02-git.tex 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. \input{../_preamble}
  2. \input{../_preamble_bbl}
  3. % \usepackage{biblatex}
  4. % \addbibresource{../bibliography}
  5. \usepackage{menukeys}
  6. \title{Git}
  7. \usepackage{float}
  8. \usepackage{dingbat}
  9. \usepackage[newfloat]{minted}
  10. \SetupFloatingEnvironment{listing}{listname=Listings}
  11. \setminted{
  12. bgcolor=Lavender,
  13. breaklines,
  14. breaksymbolright=\small\carriagereturn}
  15. \setmintedinline{bgcolor=Lavender}
  16. \usepackage{capt-of}
  17. \usepackage{soul}
  18. \makeindex[name=cmds, intoc, title={Liste des commandes et
  19. instructions}, options={-s \jobname.ist}]
  20. \NewDocumentCommand{\commande}{s m O{}}{
  21. \IfBooleanTF{#1}{\index[cmds]{#2@\texttt{#2}|#3textbf}}
  22. {\index[cmds]{#2@\texttt{#2}#3}}
  23. }
  24. \NewDocumentCommand{\inputfile}{O{} m m O{application/x-sh}}{
  25. \marginpar{\attachandlink{scripts/#3}[#4]{Fichier
  26. attaché}{\textcolor{blue}{Ouvrir le fichier}}}
  27. \inputminted[#1]{#2}{scripts/#3}
  28. }
  29. \usepackage{pdflscape}
  30. \usepackage{adjustbox}
  31. \begin{document}
  32. \maketitle
  33. \renewcommand{\contentsname}{Sommaire}
  34. \tableofcontents
  35. \listoffigures
  36. % \listoflistings
  37. % \needspace{3\baselineskip}
  38. % \listoftables
  39. \chapter{Introduction}
  40. \label{cha:introduction}
  41. \paragraph{Avertissement}
  42. Dans les pages qui suivent, on cherche à donner au lecteur quelques
  43. éléments sur la notion de \emph{système de contrôle de version} en
  44. général et sur \emph{Git} en particulier. L'ouvrage de référence, par
  45. \citeauthor{Chacon.Straub2018}, \citetitle{Chacon.Straub2018}, traduit
  46. en français, est disponible en ligne\autocite{Chacon.Straub2018}.
  47. \section{Les systèmes de contrôle de version}
  48. \label{sec:vers-contr-syst}
  49. Les \enquote{systèmes de contrôle de version}, en anglais
  50. \emph{version control systems} (VCS), sont des logiciels qui
  51. permettent de suivre toutes les modifications des fichiers et des
  52. répertoires qui se trouvent dans un répertoire donné. À partir du
  53. moment où l'on décide de suivre le contenu d'un répertoire, on peut
  54. retrouver l'état qui était le sien dans le passé à tout moment.
  55. Supposons que l'on ait quelque part modifié un paragraphe dans un
  56. texte, ajouté ou retranché des lignes: le système de contrôle de
  57. version permet alors de retrouver la chronologie de toutes les
  58. modifications et de les afficher clairement, l'une après l'autre. On a
  59. ainsi l'assurance de ne jamais rien perdre de son travail.
  60. Le contrôle de version permet également de travailler en même temps
  61. sur différentes \emph{branches}. On distingue ainsi la \emph{branche
  62. principale} de toutes les \emph{branches secondaires} que l'on peut
  63. ouvrir à tout moment. Prenons un exemple: à un moment donné, on
  64. souhaite revenir sur une page complexe que l'on a rédigée et y
  65. apporter des modifications. Mais pour autant, on n'approuve pas encore
  66. ces modifications et on voudrait ne rien perdre de la version
  67. originale. On ouvre alors une \emph{branche secondaire} dans laquelle
  68. on modifie à souhait la page. Durant tout le travail sur la branche
  69. secondaire, le travail enregistré dans la branche principale n'est pas
  70. altéré. Une fois terminé le travail sur la branche secondaire, on peut
  71. l'abandonner ou bien, si le résultat est satisfaisant, le
  72. conserver. Dans ce cas, on demande au système de contrôle de version
  73. de \emph{fusionner} dans la branche principale la branche secondaire
  74. sur laquelle on a travaillé. Puis on continue le travail dans la
  75. branche principale, après avoir effacé la branche secondaire, tout en
  76. sachant qu'à tout moment, toutes les étapes de ces modifications
  77. peuvent être retrouvées. Bien entendu, le système permet d'ouvrir
  78. simultanément autant de branches qu'on le souhaite.
  79. \subsection{Différents concepts, différentes approches}
  80. \label{sec:diff-conc-diff}
  81. On distingue trois types de systèmes de contrôle de version:
  82. \begin{enumerate}
  83. \item \textbf{Les systèmes locaux} qui enregistrent les modifications
  84. dans une base de données. Quand un fichier est modifié, ces systèmes
  85. enregistrent non pas les deux versions du fichier modifié, mais un
  86. seul fichier, en plus du fichier initial, dans lequel sont
  87. simplement notées les \emph{différences} de l'un à l'autre.
  88. \item \textbf{Les systèmes centralisés} qui font la même chose que les
  89. systèmes locaux, mais dans lesquels la base de données se trouve sur
  90. un serveur. L'avantage est que l'on peut alors organiser un travail
  91. de groupe. Mais l'inconvénient est que si le serveur est en panne,
  92. alors la base de données est inaccessible et personne ne peut
  93. travailler.
  94. \item \textbf{Les systèmes distribués} dans lesquels les différents
  95. utilisateurs travaillent non pas sur des fichiers reconstitués à
  96. l'aide de la somme des modifications enregistrées sur un serveur,
  97. mais sur une version autonome et dupliquée de tous les fichiers qui
  98. sont sur le serveur. Chacun travaille sur ses fichiers, même hors
  99. réseau. Puis une fois le travail terminé, on envoie sur le serveur
  100. un nouvel état de la base de données que les autres peuvent
  101. synchroniser à tout moment.
  102. \end{enumerate}
  103. Git est un système de contrôle de version \emph{distribué}. Par
  104. rapport à d'autres systèmes de la même catégorie, il offre un avantage
  105. considérable: celui de travailler non pas sur les \emph{différences}
  106. entre les modifications des fichiers, mais sur des \emph{instantanés}
  107. complets. Prenons un exemple. Soit le fichier suivant
  108. (\verb|recherche.txt|):\label{ref:recherche}
  109. \begin{minted}[linenos]{text}
  110. PREMIÈRE PARTIE
  111. ===============
  112. COMBRAY
  113. -------
  114. I
  115. Longtemps, je me suis couché très tôt. Parfois, à peine ma
  116. bougie éteinte, mes yeux se fermaient si vite que j'avais juste le
  117. temps de me dire: «Je m'endors.»
  118. \end{minted}
  119. Puis l'auteur se ravise et écrit:
  120. \begin{minted}[linenos]{text}
  121. PREMIÈRE PARTIE
  122. ===============
  123. COMBRAY
  124. -------
  125. I
  126. Longtemps, je me suis couché de bonne heure. Parfois, à peine ma
  127. bougie éteinte, mes yeux se fermaient si vite que je n'avais pas le
  128. temps de me dire: «Je m'endors.»
  129. \end{minted}
  130. Si l'on demande maintenant à un système informatique d'analyser les
  131. différences entre les deux états de \verb|recherche.txt|, il pourra
  132. produire un résultat comparable à celui-ci:
  133. \label{ref:diff}
  134. \begin{minted}[linenos,escapeinside=||]{text}
  135. --- recherche.txt 2018-10-03 12:35:05.848903296 +0200
  136. +++ recherche.txt 2018-10-03 12:31:04.292356175 +0200
  137. |\textcolor{Blue}{@@ -6,6 +6,6 @@}|
  138. I
  139. |\textcolor{Red}{-Longtemps, je me suis couché très tôt. Parfois, à peine ma}|
  140. |\textcolor{Red}{-bougie éteinte, mes yeux se fermaient si vite que j'avais juste le}|
  141. |\textcolor{Green}{+Longtemps, je me suis couché de bonne heure. Parfois, à peine ma}|
  142. |\textcolor{Green}{+bougie éteinte, mes yeux se fermaient si vite que je n'avais pas le}|
  143. temps de me dire: «Je m'endors.»
  144. \end{minted}
  145. \paragraph{Commentaire}
  146. La ligne~3 du rapport ci-dessus permet de comprendre que les
  147. modifications n'interviennent pas avant la ligne~6 du fichier original
  148. \verb|recherche.txt|. Ensuite, nous trouvons les modifications,
  149. entourées de \emph{deux lignes non modifiées qui donnent le contexte}:
  150. ce sont les lignes~5 et 10 du rapport, qui renvoient respectivement
  151. aux lignes~7 et 11 du fichier original. Enfin, nous trouvons les
  152. modifications: dans le rapport, les lignes~6 et 7, rendues en rouge et
  153. précédées du signe $-$, ont été remplacées dans la deuxième version
  154. par les lignes~8 et 9, rendues en vert, et précédées du signe $+$.
  155. Les systèmes de contrôle de version peuvent donc procéder de deux
  156. manières différentes:
  157. \begin{enumerate}
  158. \item Enregistrer le fichier original seulement, puis tous les
  159. rapports successifs qui donnent les modifications. Ainsi, pour
  160. donner l'état le plus récent d'un fichier, il suffit de prendre
  161. l'original puis de lui appliquer toutes les modifications
  162. successives.
  163. \item Enregistrer toutes les versions successives des fichiers sous la
  164. forme d'\emph{instantanés}. Dans ce cas, les rapports qui
  165. enregistrent les modifications ne sont pas eux-mêmes enregistrés,
  166. mais peuvent toujours être produits à partir de deux instantanés
  167. enregistrés. \textbf{C'est ainsi que procède Git}.
  168. \end{enumerate}
  169. Bien entendu, quand on travaille sur de nombreux fichiers
  170. simultanément et que, d'une étape à l'autre de son travail, on n'en
  171. modifie que quelques-uns, Git ne prend pas d'instantané des fichiers
  172. non modifiés. Au lieu de faire cela, il enregistre simplement un
  173. \emph{pointeur} vers le dernier instantané du fichier, c'est-à-dire
  174. vers la dernière version modifiée de ce fichier.
  175. Cette méthode présente de nombreux avantages dont le plus évident
  176. tient à la sécurité. En effet, les systèmes qui enregistrent seulement
  177. les rapports de modifications ne sont plus en mesure de restituer un
  178. fichier donné si l'un de ces rapports est corrompu. Si un chaînon est
  179. manquant, c'est toute la chaîne qui est brisée. Git n'est pas
  180. vulnérable sur ce point.
  181. \section{Prise en main de Git}
  182. \label{sec:prise-en-main}
  183. \href{https://notabug.org/ralessi/courses/wiki#installation-de-git}{Une
  184. fois Git installé}, il faut l'initialiser en lui indiquant votre nom
  185. et votre email. Pour cela, il suffit d'entrer successivement les deux
  186. lignes suivantes, en veillant à substituer à la fin de chaque ligne
  187. les informations de l'exemple par celles de votre identité. On
  188. veillera également à placer le prénom et le nom, séparé par un espace,
  189. entre guillemets doubles:
  190. \begin{minted}[linenos]{text}
  191. git config --global user.name "John Doe"
  192. git config --global user.email johndoe@example.com
  193. \end{minted}
  194. Ensuite, \href{./01-ligne-de-commande.pdf}{muni du cours sur la ligne
  195. de commande}, il est possible de créer un répertoire de
  196. travail. Nous allons créer ce répertoire à l'intérieur de notre
  197. répertoire \verb|Documents|, puis nous rendre à l'intérieur de ce
  198. répertoire à l'aide de la commande \verb|cd|:
  199. \begin{minted}{text}
  200. [robert@kiddo ~]$ cd Documents
  201. [robert@kiddo Documents]$ mkdir travail
  202. [robert@kiddo Documents]$ cd travail
  203. [robert@kiddo travail]$
  204. \end{minted}
  205. L'étape suivante consiste à demander à Git de suivre le contenu de ce
  206. répertoire:
  207. \begin{minted}{text}
  208. [robert@kiddo travail]$ git init
  209. Dépôt Git vide initialisé dans /home/robert/Documents/travail/.git/
  210. \end{minted}
  211. La réponse donnée par Git nous indique où sera maintenue sa base de
  212. données: dans un
  213. \href{./01-ligne-de-commande.pdf#lnk_hidden}{répertoire caché}
  214. \verb|.git| à l'intérieur du répertoire \verb|travail|.
  215. Commençons donc le travail. À l'aide d'un éditeur de texte, saisissons
  216. le fichier \mintinline{text}|recherche.txt| donné
  217. \vpageref{ref:recherche} et enregistrons-le dans sa première version.
  218. La commande suivante \verb|git status| demande à Git de nous
  219. \emph{fournir un état} du répertoire:
  220. \begin{minted}[linenos,escapeinside=||]{text}
  221. [robert@kiddo travail]$ git status
  222. Sur la branche master
  223. Validation initiale
  224. Fichiers non suivis:
  225. (utilisez "git add <fichier>..." pour inclure dans ce qui sera validé)
  226. |\textcolor{Red}{recherche.txt}|
  227. aucune modification ajoutée à la validation mais des fichiers non suivis sont présents (utilisez "git add" pour les suivre)
  228. \end{minted}
  229. \paragraph{Commentaire}
  230. Comme on le voit, Git est toujours très explicite. Voici ce qu'il faut
  231. retenir ici de ce rapport:
  232. \begin{enumerate}
  233. \item Ligne~2: par défaut, la \emph{branche principale} est appelée
  234. par Git \verb|master|.
  235. \item Ligne~6 et suivantes: Git donne une simple liste de fichiers
  236. trouvés dans le répertoire et indique qu'on ne lui a pas (encore)
  237. demandé de les \emph{suivre}. C'est un point important qu'il faut
  238. bien comprendre: \emph{Git ne suivra que les fichiers qu'on lui a
  239. demandé d'indexer}.
  240. \item Ligne~7: Git nous donne la commande à utiliser pour indexer le
  241. fichier qui a été trouvé: \mintinline{bash}|git add <fichier>|
  242. \end{enumerate}
  243. Exécutons cette commande, puis demandons à Git un nouveau rapport:
  244. \begin{minted}[linenos,escapeinside=||]{text}
  245. [robert@kiddo travail]$ git add recherche.txt
  246. [robert@kiddo travail]$ git status
  247. Sur la branche master
  248. Validation initiale
  249. Modifications qui seront validées :
  250. (utilisez "git rm --cached <fichier>..." pour désindexer)
  251. |\textcolor{Green}{nouveau fichier : recherche.txt}|
  252. \end{minted}
  253. La commande \mintinline{bash}|git add recherche.txt| a eu pour effet
  254. de placer \verb|recherche.txt| \emph{dans la zone d'index de Git} que
  255. l'on appelle \emph{zone de travail} ou \emph{staging area}.
  256. La dernière opération consiste à enregistrer le fichier dans la base
  257. de données de Git: cela se fait à l'aide de la commande
  258. \mintinline{bash}|git commit|. La syntaxe de cette commande est la
  259. suivante:
  260. \begin{minted}{bash}
  261. git commit <fichier> -m "<message>"
  262. \end{minted}
  263. où \verb|<fichier>| est le nom du ou des fichiers à enregistrer, et
  264. \verb|<message>| une petite ligne susceptible de servir
  265. d'aide-mémoire:
  266. \begin{minted}{text}
  267. [robert@kiddo travail]$ git commit recherche.txt -m "version initiale"
  268. [master (commit racine) fa1ec00] version initiale
  269. 1 file changed, 11 insertions(+)
  270. create mode 100644 recherche.txt
  271. \end{minted}
  272. \paragraph{Poursuite du travail}
  273. Git enregistre tous les \emph{commits} dans un fichier journal, en
  274. anglais \emph{log file} ou plus simplement \emph{log}. Dans les
  275. exemples qui suivent, nous avons inséré dans le fichier
  276. \verb|recherche.txt| donné \vpageref{ref:recherche} les modifications
  277. correspondant à la deuxième version du fichier.
  278. Comme ce fichier est indexé, la commande \verb|git diff| nous montre
  279. immédiatement quelles sont les différences (v. plus haut
  280. \vpageref{ref:diff}):
  281. \begin{minted}[linenos,escapeinside=||]{text}
  282. [robert@kiddo travail]$ git diff
  283. diff --git a/recherche.txt b/recherche.txt
  284. index 3baf502..f230132 100644
  285. --- a/recherche.txt
  286. +++ b/recherche.txt
  287. |\textcolor{Blue}{@@ -6,6 +6,6 @@}| COMBRAY
  288. I
  289. |\textcolor{Red}{-Longtemps, je me suis couché très tôt. Parfois, à peine ma}|
  290. |\textcolor{Red}{-bougie éteinte, mes yeux se fermaient si vite que j'avais juste le}|
  291. |\textcolor{Green}{+Longtemps, je me suis couché de bonne heure. Parfois, à peine ma}|
  292. |\textcolor{Green}{+bougie éteinte, mes yeux se fermaient si vite que je n'avais pas le}|
  293. temps de me dire: «Je m'endors.»
  294. \end{minted}
  295. Pour terminer, enregistrons ces modifications:
  296. \begin{minted}{text}
  297. [robert@kiddo travail]$ git commit recherche.txt -m "nouvelle version de l'incipit"
  298. [master 83b6c3e] nouvelle version de l'incipit
  299. 1 file changed, 2 insertions(+), 2 deletions(-)
  300. \end{minted}
  301. Et demandons à Git de nous fournir un extrait de son journal:
  302. \begin{minted}[linenos,escapeinside=||]{text}
  303. [robert@kiddo travail]$ git log
  304. |\textcolor{Brown}{commit 83b6c3e6dad72116eac5ce7d1ba70968e4e57ebb}|
  305. Author: Robert Alessi <alessi@robertalessi.net>
  306. Date: Wed Oct 3 15:05:32 2018 +0200
  307. nouvelle version de l'incipit
  308. |\textcolor{Brown}{commit fa1ec001efdca9c69cc768dc9cf83706bdb6e603}|
  309. Author: Robert Alessi <alessi@robertalessi.net>
  310. Date: Wed Oct 3 14:49:10 2018 +0200
  311. version initiale
  312. \end{minted}
  313. Nous voyons aux lignes~2 et 8 qu'à chaque \emph{commit} est associé un
  314. \emph{numéro de registre}, en notation hexadécimale, formé d'une
  315. séquence de~40 caractères allant de \verb|0| à \verb|9| et de \verb|a|
  316. à \verb|f|.
  317. \subsection{Résumé des commandes}
  318. \label{sec:resume-des-commandes}
  319. \begin{enumerate}
  320. \item \verb|git config --global| $\rightarrow$ paramétrage initial de
  321. Git.
  322. \item \verb|git init| $\rightarrow$ initialisation de Git dans un
  323. nouveau répertoire.
  324. \item \verb|git status| $\rightarrow$ demande à Git un \emph{rapport
  325. d'état}.
  326. \item \verb|git add| $\rightarrow$ indexe des fichiers dans la zone de
  327. travail. Les fichiers indexés sont ceux qui seront suivis par
  328. Git.
  329. \item \verb|git commit <fichier> -m "<message>"| $\rightarrow$
  330. enregistre dans la base de données de Git les versions modifiées des
  331. fichiers sous forme d'instantanés.
  332. \item \verb|git diff| $\rightarrow$ montre les différences entre la
  333. version actuelle des fichiers et leur dernière version enregistrée
  334. par %
  335. \verb|git commit|.
  336. \item \verb|git log| $\rightarrow$ affiche le journal de Git.
  337. \end{enumerate}
  338. \section{Git en mode graphique}
  339. \label{sec:git-gui}
  340. \hfill\verb|../.. à suivre|
  341. \begin{landscape}
  342. \begin{figure}
  343. \centering
  344. \adjustimage{frame,width=\linewidth}{images/02-gitk.png}
  345. \caption{gitk}
  346. \label{fig:gitk}
  347. \end{figure}
  348. \end{landscape}
  349. \end{document}