hgbook

annotate fr/tour-merge.tex @ 961:dd7511a5c127

relecture et traduction de la fin de tour-merge
author Wilk
date Wed Mar 25 15:49:24 2009 +0100 (2009-03-25)
parents 2cd5d582c956
children bac1c207c76d
rev   line source
belaran@953 1 \chapter{Un rapide tour de Mercurial: fusionner les travaux}
bos@95 2 \label{chap:tour-merge}
bos@94 3
Wilk@961 4 Nous avons maintenant étudié comment cloner un dépôt, effectuer
belaran@953 5 des changements dedans, et récupérer ou transférer depuis un
belaran@953 6 autre dépôt. La prochaine étape est donc de \emph{fusionner} les
belaran@953 7 modifications de différents dépôts.
belaran@953 8
belaran@953 9 \section{Fusionner différents travaux} %%%TODO: better translation
belaran@953 10 %%% for 'Merging streams of work' ?
belaran@953 11 La fusion\footnote{NdT: Je garde fusion mais le jargon professionnel
belaran@954 12 emploiera généralement le terme \textit{merge}.} est un aspect
Wilk@961 13 fondamental lorsqu'on travaille avec un gestionnaire de source
belaran@954 14 distribué.
bos@94 15 \begin{itemize}
belaran@953 16 \item Alice et Bob ont chacun une copie personnelle du dépôt d'un
belaran@953 17 projet sur lequel ils collaborent. Alice corrige un \textit{bug}
belaran@953 18 dans son dépôt, et Bob ajoute une nouvelle fonctionnalité dans le
belaran@953 19 sien. Ils veulent un dépôt partagé avec à la fois le correctif du
belaran@953 20 \textit{bug} et la nouvelle fonctionnalité.
belaran@953 21 \item Je travaille régulièrement sur plusieurs tâches différentes sur
Wilk@961 22 un seul projet en même temps, chacune isolée dans son propre dépôt.
belaran@953 23 Travailler ainsi signifie que je dois régulièrement fusionner une
belaran@953 24 partie de mon code avec celui des autres.
bos@94 25 \end{itemize}
bos@94 26
Wilk@961 27 Parce que la fusion est une opération si commune à réaliser,
belaran@954 28 Mercurial la rend facile. Étudions ensemble le déroulement des opérations.
Wilk@961 29 Nous commencerons encore par faire un clone d'un autre dépôt (vous voyez
Wilk@961 30 que l'on fait ça tout le temps ?) puis nous ferons quelques modifications
belaran@953 31 dessus.
bos@94 32 \interaction{tour.merge.clone}
belaran@953 33 Nous devrions avoir maintenant deux copies de \filename{hello.c} avec
belaran@953 34 des contenus différents. Les historiques de ces deux dépôts ont aussi
belaran@953 35 divergés, comme illustré dans la figure~\ref{fig:tour-merge:sep-repos}.
belaran@953 36
bos@94 37 \interaction{tour.merge.cat}
bos@94 38
bos@99 39 \begin{figure}[ht]
bos@99 40 \centering
bos@99 41 \grafix{tour-merge-sep-repos}
belaran@953 42 \caption{Historiques récent divergents des dépôts \dirname{my-hello}
belaran@953 43 et \dirname{my-new-hello}}
bos@99 44 \label{fig:tour-merge:sep-repos}
bos@99 45 \end{figure}
bos@99 46
belaran@953 47 Nous savons déjà que récupérer les modifications depuis notre dépôt
belaran@953 48 \dirname{my-hello} n'aura aucun effet sur l'espace de travail.
belaran@953 49
bos@94 50 \interaction{tour.merge.pull}
belaran@953 51
belaran@954 52 Néanmoins, la commande \hgcmd{pull} nous indique quelque chose au
belaran@953 53 sujet des ``heads''.
belaran@953 54
belaran@953 55 \subsection{\textit{Head changesets}} %%%TODO: Hard (too?) to translate
belaran@953 56
belaran@953 57 Une \textit{head}\footnote{NdT: Je garde \textit{head} que j'accorde
Wilk@961 58 au féminin comme la coutume orale l'a imposée.} est un \textit{changeset}
belaran@953 59 sans descendants, ou enfants, comme on les désigne parfois. La révision
belaran@953 60 \textit{tip} est une \textit{head}, car la dernière révision dans un dépôt
belaran@953 61 n'a aucun enfant, mais il est important de noter qu'un dépôt peut contenir
belaran@953 62 plus d'une \textit{head}.
bos@99 63
bos@99 64 \begin{figure}[ht]
bos@99 65 \centering
bos@99 66 \grafix{tour-merge-pull}
Wilk@961 67 \caption{Contenu d'un dépôt après avoir transféré le contenu du dépôt
belaran@953 68 \dirname{my-hello} dans le dépôt \dirname{my-new-hello}}
bos@99 69 \label{fig:tour-merge:pull}
bos@99 70 \end{figure}
bos@99 71
belaran@953 72 Dans la figure~\ref{fig:tour-merge:pull}, vous pouvez constater l'effet
belaran@953 73 d'un \textit{pull} depuis le dépôt \dirname{my-hello} dans le dépôt
belaran@953 74 \dirname{my-new-hello}. L'historique qui était déjà présent dans le dépôt
belaran@953 75 \dirname{my-new-hello} reste intact, mais une nouvelle révision a été
belaran@953 76 ajoutée. En vous reportant à la figure~\ref{fig:tour-merge:sep-repos},
belaran@953 77 vous pouvez voir que le \textit{\emph{changeset ID}} reste le même dans
belaran@953 78 le nouveau dépôt, mais que le \emph{numéro de révision} reste le même.
Wilk@961 79 (Ceci est un parfait exemple du fait il n'est fiable d'utiliser les
belaran@953 80 numéro de révision lorsque l'on discute d'un \textit{changeset}.) Vous
Wilk@961 81 pouvez voir les \texit{heads} présentes dans le dépôt en utilisant la
belaran@953 82 commande \hgcmd{heads}.
bos@94 83 \interaction{tour.merge.heads}
bos@102 84
belaran@953 85 \subsection{Effectuer la fusion}
belaran@953 86
belaran@953 87 Que se passe-t-il quand vous essayez d'utiliser la commande \hgcmd{update}
belaran@953 88 pour mettre à jour votre espace de travail au nouveau \textit{tip}.
bos@94 89 \interaction{tour.merge.update}
belaran@953 90 Mercurial nous prévient que la commande \hgcmd{update} n'effectuera pas
belaran@953 91 la fusion, il ne veut pas mettre à jour l'espace de travail quand il
belaran@953 92 estime que nous pourrions avoir besoin d'une fusion, à moins de lui
belaran@953 93 forcer la main. À la place, il faut utiliser la commande \hgcmd{merge}
belaran@953 94 pour fusionner les deux \textit{heads}.
bos@94 95 \interaction{tour.merge.merge}
bos@100 96
bos@100 97 \begin{figure}[ht]
bos@100 98 \centering
bos@100 99 \grafix{tour-merge-merge}
belaran@953 100 \caption{Espace de travail et dépôt lors d'une fusion, et dans le
belaran@953 101 \textit{commit} qui suit.}
bos@100 102 \label{fig:tour-merge:merge}
bos@100 103 \end{figure}
bos@100 104
Wilk@961 105 Ceci met à jour l'espace de travail de manière à ce qu'il contienne
belaran@954 106 les modifications des \emph{deux} \textit{heads}, ce qui apparaît dans
belaran@953 107 les sorties de la commande \hgcmd{parents} et le contenu de
belaran@953 108 \filename{hello.c}.
bos@94 109 \interaction{tour.merge.parents}
bos@102 110
belaran@954 111 \subsection{Effectuer le \textit{commit} du résultat de la fusion}
belaran@954 112
Wilk@961 113 Dès l'instant où vous avez effectué une fusion, \hgcmd{parents} vous
Wilk@961 114 affichera deux parents, avant que vous n'exécutiez la commande
belaran@954 115 \hgcmd{commit} sur le résultat de la fusion.
bos@94 116 \interaction{tour.merge.commit}
Wilk@961 117 Nous avons maintenant un nouveau \textit{tip}, remarquez qu'il contient
belaran@953 118 \emph{à la fois} nos anciennes \textit{heads} et leurs parents. Ce sont
Wilk@961 119 les mêmes révisions que nous avions affichées avec la commande
belaran@953 120 \hgcmd{parents}.
belaran@953 121
bos@94 122 \interaction{tour.merge.tip}
belaran@953 123 Dans la figure~\ref{fig:tour-merge:merge}, vous pouvez voir une représentation
belaran@953 124 de ce qui se passe dans l'espace de travail pendant la fusion, et comment ceci
belaran@953 125 affecte le dépôt lors du \textit{commit}. Pendant la fusion, l'espace de travail,
belaran@953 126 qui a deux \texit{changesets} comme parents, voit ces derniers devenir le parent
belaran@953 127 d'un nouveau \textit{changeset}.
belaran@953 128
belaran@953 129 \section{Fusionner les modifications en conflit}
belaran@953 130
Wilk@961 131 La plupart des fusions sont assez simples à réaliser, mais parfois
Wilk@961 132 vous vous retrouverez à fusionner des fichiers où la modification touche
belaran@953 133 la même portion de code, au sein d'un même fichier. À moins que ces
belaran@953 134 modification ne soient identiques, ceci aboutira à un \emph{conflit},
belaran@954 135 et vous devrez décider comment réconcilier les différentes modifications
belaran@953 136 dans un tout cohérent.
bos@103 137
bos@103 138 \begin{figure}[ht]
bos@103 139 \centering
bos@103 140 \grafix{tour-merge-conflict}
belaran@953 141 \caption{Modifications conflictuelles dans un document}
bos@103 142 \label{fig:tour-merge:conflict}
bos@103 143 \end{figure}
bos@103 144
belaran@953 145 La figure~\ref{fig:tour-merge:conflict} illustre un cas de modifications
belaran@953 146 conflictuelles dans un document. Nous avons commencé avec une version simple
Wilk@961 147 de ce fichier, puis nous avons ajouté des modifications, pendant que
Wilk@961 148 quelqu'un d'autre modifiait le même texte. Notre tâche dans la résolution
belaran@953 149 du conflit est de décider à quoi le fichier devrait ressembler.
belaran@953 150
belaran@953 151 Mercurial n'a pas de mécanisme interne pour gérer les conflits.
belaran@954 152 À la place, il exécute un programme externe appelé \command{hgmerge}.
belaran@953 153 Il s'agit d'un script shell qui est embarqué par Mercurial, vous
belaran@953 154 pouvez le modifier si vous le voulez. Ce qu'il fait par défaut est
belaran@953 155 d'essayer de trouver un des différents outils de fusion qui seront
Wilk@961 156 probablement installés sur le système. Il commence par les outils
Wilk@961 157 totalement automatiques, et s'ils échouent (parce que la résolution
Wilk@961 158 du conflit nécessite une intervention humaine) ou s'ils sont absents,
Wilk@961 159 le script tentera d'exécuter certains outils graphiques de fusion.
belaran@953 160
belaran@953 161 Il est aussi possible de demander à Mercurial d'exécuter un autre
belaran@953 162 programme ou un autre script au lieu de la commande \command{hgmerge},
belaran@954 163 en définissant la variable d'environnement \envar{HGMERGE} avec le nom
belaran@953 164 du programme de votre choix.
belaran@953 165
belaran@953 166 \subsection{Utiliser un outil graphique de fusion}
belaran@953 167
belaran@953 168 Mon outil de fusion préféré est \command{kdiff3}, que j'utilise ici
Wilk@961 169 pour illustrer les fonctionnalités classiques des outils graphiques
belaran@953 170 de fusion. Vous pouvez voir une capture d'écran de l'utilisation de
belaran@953 171 \command{kdiff3} dans la figure~\ref{fig:tour-merge:kdiff3}. Cet outil
belaran@953 172 effectue une \emph{fusion \textit{three-way}}, car il y a trois différentes
Wilk@961 173 versions du fichier qui nous intéressent. Le fichier découpe la partie
belaran@953 174 supérieure de la fenêtre en trois panneaux:
belaran@953 175
bos@103 176 \begin{itemize}
Wilk@961 177 \item A gauche on a la version de \emph{base} du fichier, soit ~la plus
Wilk@961 178 récente version des deux versions que l'on souhaite fusionner.
belaran@953 179 \item Au centre, il y a ``notre'' version du fichier, avec le contenu
belaran@953 180 que nous avons modifié.
Wilk@961 181 \item Sur la droite, on trouve ``leur'' version du fichier, celui qui
Wilk@961 182 contient le \textit{changeset} que nous souhaitons intégrer.
bos@103 183 \end{itemize}
belaran@953 184
belaran@953 185 Dans le panneau en dessous, on trouve le \emph{résultat} actuel de notre
Wilk@961 186 fusion. Notre tâche consiste donc à remplacement tous les textes en rouges,
Wilk@961 187 qui indiquent des conflits non résolus, avec une fusion manuelle et pertinente
belaran@953 188 de ``notre'' version et de la ``leur''.
belaran@953 189
Wilk@961 190 Tous les quatre panneaux sont \emph{accrochés ensemble}, si nous déroulons
belaran@953 191 les ascenseurs verticalement ou horizontalement dans chacun d'entre eux, les
Wilk@961 192 autres sont mis à jour avec la section correspondante dans leurs fichiers
Wilk@961 193 respectifs.
bos@103 194
bos@103 195 \begin{figure}[ht]
bos@103 196 \centering
bos@103 197 \grafix{kdiff3}
Wilk@961 198 \caption{Utilisation de \command{kdiff3} pour fusionner différentes versions
belaran@953 199 d'un fichier.}
bos@103 200 \label{fig:tour-merge:kdiff3}
bos@103 201 \end{figure}
bos@103 202
belaran@953 203 Pour chaque portion de fichier posant problème, nous pouvons choisir
Wilk@961 204 de résoudre le conflit en utilisant une combinaison
belaran@953 205 de texte depuis la version de base, la notre, ou la leur. Nous pouvons
Wilk@961 206 aussi éditer manuellement les fichiers à tout moment, si c'est
belaran@953 207 nécessaire.
belaran@953 208
belaran@953 209 Il y a \emph{beaucoup} d'outils de fusion disponibles, bien trop pour
belaran@954 210 en parler de tous ici. Leurs disponibilités varient selon les plate formes
belaran@954 211 ainsi que leurs avantages et inconvénients. La plupart sont optimisé pour
belaran@953 212 la fusion de fichier contenant un texte plat, certains sont spécialisé
belaran@954 213 dans un format de fichier précis (généralement XML).
belaran@954 214
Wilk@961 215 \subsection{Un exemple concret}
belaran@954 216
belaran@954 217 Dans cet exemple, nous allons reproduire la modification de l'historique
belaran@954 218 du fichier de la figure~\ref{fig:tour-merge:conflict} ci dessus. Commençons
belaran@954 219 par créer un dépôt avec une version de base de notre document.
belaran@954 220
bos@103 221 \interaction{tour-merge-conflict.wife}
belaran@954 222 Créons un clone de ce dépôt et faisons une modification dans le fichier.
bos@103 223 \interaction{tour-merge-conflict.cousin}
Wilk@961 224 Et un autre clone, pour simuler que quelqu'un d'autre effectue une
belaran@954 225 modification sur le fichier. (Ceci pour suggérer qu'il n'est pas rare
belaran@954 226 de devoir effectuer des \textit{merge} avec vos propres travaux quand
Wilk@961 227 vous isolez les tâches dans des dépôts distincts. En effet, vous
belaran@954 228 aurez alors à trouver et résoudre certains conflits).
bos@103 229 \interaction{tour-merge-conflict.son}
belaran@954 230 Maintenant que ces deux versions différentes du même fichier sont
Wilk@961 231 créées, nous allons configurer l'environnement de manière appropriée pour
Wilk@961 232 exécuter notre \textit{merge}.
bos@103 233 \interaction{tour-merge-conflict.pull}
bos@103 234
belaran@954 235 Dans cette exemple, je n'utiliserais pas la commande Mercurial
belaran@954 236 habituelle \command{hgmerge} pour effectuer le \textit{merge},
belaran@954 237 car il me faudrait abandonner ce joli petit exemple automatisé
belaran@954 238 pour utiliser un outil graphique. À la place, je vais définir
belaran@954 239 la variable d'environnement \envar{HGMERGE} pour indiquer à
belaran@954 240 Mercurial d'utiliser la commande non-interactive \command{merge}.
Wilk@961 241 Cette dernière est embarquée par de nombreux systèmes ``à la Unix''.
Wilk@961 242 Si vous exécutez cet exemple depuis votre ordinateur, ne vous
belaran@954 243 occupez pas de définir \envar{HGMERGE}.
bos@103 244 \interaction{tour-merge-conflict.merge}
belaran@954 245 Parce que \command{merge} ne peut pas résoudre les modifications
belaran@954 246 conflictuelles, il laisse des \emph{marqueurs de différences}
belaran@954 247 \footnote{NdT: Oui, je traduis \textit{merge markers} par un sens
belaran@954 248 inverse en Français, mais je pense vraiment que c'est plus clair
belaran@954 249 comme ça...} à l'intérieur du fichier qui a des conflits, indiquant
belaran@954 250 clairement quelles lignes sont en conflits, et si elles viennent de
belaran@954 251 notre fichier ou du fichier externe.
belaran@954 252
belaran@954 253 Mercurial peut distinguer, à la manière dont la commande \command{merge}
belaran@954 254 se termine, qu'elle n'a pas été capable d'effectuer le \textit{merge},
Wilk@961 255 alors il nous indique que nous devons effectuer de nouveau cette
belaran@954 256 opération. Ceci peut être très utile si, par exemple, nous exécutons un
belaran@954 257 outil graphique de fusion et que nous le quittons sans se rendre compte
belaran@954 258 qu'il reste des conflits ou simplement par erreur.
belaran@954 259
belaran@954 260 Si le \textit{merge} automatique ou manuel échoue, il n'y a rien pour
belaran@954 261 nous empêcher de ``corriger le tir'' en modifiant nous même les fichiers,
belaran@954 262 et enfin effectuer le \textit{commit} du fichier:
bos@103 263 \interaction{tour-merge-conflict.commit}
bos@103 264
Wilk@961 265 \section{Simplification de la séquence pull-merge-commit}
bos@224 266 \label{sec:tour-merge:fetch}
bos@102 267
Wilk@961 268 La procédure pour effectuer la fusion indiquée ci-dessus est simple,
Wilk@961 269 mais requiert le lancement de trois commandes à la suite.
bos@102 270 \begin{codesample2}
bos@102 271 hg pull
bos@102 272 hg merge
bos@102 273 hg commit -m 'Merged remote changes'
bos@102 274 \end{codesample2}
Wilk@961 275
Wilk@961 276 Lors du \textit{commit} final, vous devez également saisir un message,
Wilk@961 277 qui aura vraisemblablement assez peu d'intérêt.
Wilk@961 278
Wilk@961 279 Il serait assez sympathique de pouvoir réduire le nombre d'opérations
Wilk@961 280 nécessaire, si possible. De fait Mercurial est fourni avec une
Wilk@961 281 extension appelé \hgext{fetch} qui fait justement cela.
Wilk@961 282
Wilk@961 283 Mercurial fourni un mécanisme d'extension flexible qui permet à chacun
Wilk@961 284 d'étendre ces fonctionnalités, tout en conservant le cœur de Mercurial
Wilk@961 285 léger et facile à utiliser. Certains extensions ajoutent de nouvelles
Wilk@961 286 commandes que vous pouvez utiliser en ligne de commande, alors que
Wilk@961 287 d'autres travaillent ``en coulisse,'' par exemple en ajoutant des
Wilk@961 288 possibilités au serveur.
Wilk@961 289
Wilk@961 290 L'extension \hgext{fetch} ajoute une nouvelle commande nommée, sans
Wilk@961 291 surprise, \hgcmd{fetch}. Cette extension résulte en une combinaison
Wilk@961 292 de \hgcmd{pull}, \hgcmd{update} and \hgcmd{merge}. Elle commence par
Wilk@961 293 récupérer les modifications d'un autre dépôt dans le dépôt courant.
Wilk@961 294 Si elle trouve que les modifications ajoutent une nouvelle \textit{head},
Wilk@961 295 elle effectue un \textit{merge}, et ensuite \texit{commit} le résultat
Wilk@961 296 du \textit{merge} avec un message généré automatiquement. Si aucune
Wilk@961 297 \textit{head} n'ont été ajouté, elle met à jour le répertoire de travail
Wilk@961 298 au niveau du nouveau \textit{changeset} \textit{tip}.
bos@102 299
bos@102 300 Enabling the \hgext{fetch} extension is easy. Edit your
bos@102 301 \sfilename{.hgrc}, and either go to the \rcsection{extensions} section
bos@102 302 or create an \rcsection{extensions} section. Then add a line that
bos@102 303 simply reads ``\Verb+fetch +''.
Wilk@961 304
Wilk@961 305 Activer l'extension \hgext{fetch} est facile. Modifiez votre \sfilename{.hgrc},
Wilk@961 306 et soit allez à la section \rcsection{extensions} soit créer une
Wilk@961 307 section \rcsection{extensions}. Ensuite ajoutez une ligne qui consiste
Wilk@961 308 simplement en ``\Verb+fetch =''.
Wilk@961 309
bos@102 310 \begin{codesample2}
bos@102 311 [extensions]
bos@102 312 fetch =
bos@102 313 \end{codesample2}
Wilk@961 314
Wilk@961 315 (Normalement, sur la partie droite de ``\texttt{=}'' devrait apparaître
Wilk@961 316 le chemin de l'extension, mais étant donné que l'extension \hgext{fetch}
Wilk@961 317 fait partie de la distribution standard, Mercurial sait où la trouver.)
bos@102 318
bos@84 319 %%% Local Variables:
bos@84 320 %%% mode: latex
bos@84 321 %%% TeX-master: "00book"
bos@84 322 %%% End: