hgbook

annotate fr/tour-merge.tex @ 953:e77ede0fdef8

Two third of tour-merge.tex done
author Romain PELISSE <belaran@gmail.com>
date Wed Feb 18 18:02:29 2009 +0100 (2009-02-18)
parents 547d3aa25ef0
children 2cd5d582c956
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
belaran@953 4 Nous avons maintenons étudié comment clôner 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@953 12 employera généralement le terme \textit{merge}.} est un aspect
belaran@953 13 fondamental lorsqu'on travail avec un gestionnaire de source
belaran@953 14 distribé.
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
belaran@953 22 un seul projet en même temps, chacun 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
belaran@953 27 Parce que la fusion est une opération si commune que je dois réaliser,
belaran@953 28 Mercurial la rend facile. Etudions ensemble le déroulement des opérations.
belaran@953 29 Nous commencerons par faire un clone d'encore un autre dépôt (vous voyez
belaran@953 30 comment 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@953 52 Néanmoins, la commande \hgcmd{pull} nous indique quelquechose 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
belaran@953 58 au féminin comme la coutume oral 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}
belaran@953 67 \caption{Contenu d'un dépôt après avoir transférer 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.
belaran@953 79 (Ceci est un parfait exemple de pourquoi il n'est fiable d'utiliser les
belaran@953 80 numéro de révision lorsque l'on discute d'un \textit{changeset}.) Vous
belaran@953 81 pouvez voir les \texit{heads} présente 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
belaran@953 105 Ceci met à jour de l'espace de travail de manière à ce qu'il contienne
belaran@953 106 les modifications des \emph{deux} \textit{heads}, ce qui apparait 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
bos@102 111 \subsection{Committing the results of the merge}
bos@102 112
bos@94 113 Whenever we've done a merge, \hgcmd{parents} will display two parents
bos@94 114 until we \hgcmd{commit} the results of the merge.
bos@94 115 \interaction{tour.merge.commit}
belaran@953 116 Nous avons maintenant un nouveau \textit{tip}, remarquer qu'il contient
belaran@953 117 \emph{à la fois} nos anciennes \textit{heads} et leurs parents. Ce sont
belaran@953 118 les mêmes révisions que nous avions affichés avec la commande
belaran@953 119 \hgcmd{parents}.
belaran@953 120
bos@94 121 \interaction{tour.merge.tip}
belaran@953 122 Dans la figure~\ref{fig:tour-merge:merge}, vous pouvez voir une représentation
belaran@953 123 de ce qui se passe dans l'espace de travail pendant la fusion, et comment ceci
belaran@953 124 affecte le dépôt lors du \textit{commit}. Pendant la fusion, l'espace de travail,
belaran@953 125 qui a deux \texit{changesets} comme parents, voit ces derniers devenir le parent
belaran@953 126 d'un nouveau \textit{changeset}.
belaran@953 127
belaran@953 128 \section{Fusionner les modifications en conflit}
belaran@953 129
belaran@953 130 La plupart des fusions sont assez simple à réaliser, mais parfois
belaran@953 131 vous vous trouverez à fusioner des fichiers où la modification touche
belaran@953 132 la même portion de code, au sein d'un même fichier. À moins que ces
belaran@953 133 modification ne soient identiques, ceci aboutira à un \emph{conflit},
belaran@953 134 et vous devrez décider comment réconcillier les différentes modifications
belaran@953 135 dans un tout cohérent.
bos@103 136
bos@103 137 \begin{figure}[ht]
bos@103 138 \centering
bos@103 139 \grafix{tour-merge-conflict}
belaran@953 140 \caption{Modifications conflictuelles dans un document}
bos@103 141 \label{fig:tour-merge:conflict}
bos@103 142 \end{figure}
bos@103 143
belaran@953 144 La figure~\ref{fig:tour-merge:conflict} illustre un cas de modifications
belaran@953 145 conflictuelles dans un document. Nous avons commencé avec une version simple
belaran@953 146 de ce fichier, puis nous avons ajoutés des modifications, pendant que
belaran@953 147 quelqu'un d'autre modifie le même texte. Notre tâche dans la résolution
belaran@953 148 du conflit est de décider à quoi le fichier devrait ressembler.
belaran@953 149
belaran@953 150 Mercurial n'a pas de mécanisme interne pour gérer les conflits.
belaran@953 151 À la place, il exéctue un programme externe appelé \command{hgmerge}.
belaran@953 152 Il s'agit d'un script shell qui est embarqué par Mercurial, vous
belaran@953 153 pouvez le modifier si vous le voulez. Ce qu'il fait par défaut est
belaran@953 154 d'essayer de trouver un des différents outils de fusion qui seront
belaran@953 155 probablement installé sur le système. Il commence par les outils
belaran@953 156 totalement automatique, et si ils échouent (parce que la résolution
belaran@953 157 du conflit nécessite une intervention humaine) ou si ils sont absents,
belaran@953 158 le script tente d'exécuter certains outils graphiques de fusion.
belaran@953 159
belaran@953 160 Il est aussi possible de demander à Mercurial d'exécuter un autre
belaran@953 161 programme ou un autre script au lieu de la commande \command{hgmerge},
belaran@953 162 en définissant la variable d'environement \envar{HGMERGE} avec le nom
belaran@953 163 du programme de votre choix.
belaran@953 164
belaran@953 165 \subsection{Utiliser un outil graphique de fusion}
belaran@953 166
belaran@953 167 Mon outil de fusion préféré est \command{kdiff3}, que j'utilise ici
belaran@953 168 pour illustré les fonctionnalités classiques des outils graphiques
belaran@953 169 de fusion. Vous pouvez voir une capture d'écran de l'utilisation de
belaran@953 170 \command{kdiff3} dans la figure~\ref{fig:tour-merge:kdiff3}. Cet outil
belaran@953 171 effectue une \emph{fusion \textit{three-way}}, car il y a trois différentes
belaran@953 172 versions du fichier qui nous intéresse. Le fichier découpe la partie
belaran@953 173 supérieure de la fenêtre en trois panneaux:
belaran@953 174
bos@103 175 \begin{itemize}
belaran@953 176 \item A gauche on la version de \emph{base} du fichier, soit ~la plus
belaran@953 177 récente version des deux versions qu'on souhaite fusionner.
belaran@953 178 \item Au centre, il y a ``notre'' version du fichier, avec le contenu
belaran@953 179 que nous avons modifié.
belaran@953 180 \item Sur la droite, on trouve ``leur'' version du fichier, celui qui qui
belaran@953 181 contient le \textit{changeset} que nous souhaitons intégré.
bos@103 182 \end{itemize}
belaran@953 183
belaran@953 184 Dans le panneau en dessous, on trouve le \emph{résultat} actuel de notre
belaran@953 185 fusion. Notre tâche consiste donc à remplacement tout les textes en rouges,
belaran@953 186 qui indiquent des conflits non résolus, avec un fusion manuel et pertinente
belaran@953 187 de ``notre'' version et de la ``leur''.
belaran@953 188
belaran@953 189 Tout les quatres panneaux sont \emph{accrochés ensemble}, si nous déroulons
belaran@953 190 les ascenseurs verticalement ou horizontalement dans chacun d'entre eux, les
belaran@953 191 autres sont mise à jours avec la section correspondantes dans leurs fichiers.
bos@103 192
bos@103 193 \begin{figure}[ht]
bos@103 194 \centering
bos@103 195 \grafix{kdiff3}
belaran@953 196 \caption{Utilisation de \command{kdiff3} pour fusionner différents versions
belaran@953 197 d'un fichier.}
bos@103 198 \label{fig:tour-merge:kdiff3}
bos@103 199 \end{figure}
bos@103 200
belaran@953 201 Pour chaque portion de fichier posant problème, nous pouvons choisir
belaran@953 202 de résoudre le le conlfit en utilisant en utilisant une combinaison
belaran@953 203 de texte depuis la version de base, la notre, ou la leur. Nous pouvons
belaran@953 204 aussi éditer manuellement les fichiers à tous moments, si c'est
belaran@953 205 nécessaire.
belaran@953 206
belaran@953 207 Il y a \emph{beaucoup} d'outils de fusion disponibles, bien trop pour
belaran@953 208 en parler de tous ici. Leurs disponibilités varient selon les plateformes
belaran@953 209 ainsi que leurs avantages et incovénients. La plupart sont optimisé pour
belaran@953 210 la fusion de fichier contenant un texte plat, certains sont spécialisé
belaran@953 211 dans un format de fichier précis (générallement XML).
bos@103 212
bos@103 213 \subsection{A worked example}
bos@103 214
bos@103 215 In this example, we will reproduce the file modification history of
bos@103 216 figure~\ref{fig:tour-merge:conflict} above. Let's begin by creating a
bos@103 217 repository with a base version of our document.
bos@103 218 \interaction{tour-merge-conflict.wife}
bos@103 219 We'll clone the repository and make a change to the file.
bos@103 220 \interaction{tour-merge-conflict.cousin}
bos@103 221 And another clone, to simulate someone else making a change to the
bos@103 222 file. (This hints at the idea that it's not all that unusual to merge
bos@103 223 with yourself when you isolate tasks in separate repositories, and
bos@103 224 indeed to find and resolve conflicts while doing so.)
bos@103 225 \interaction{tour-merge-conflict.son}
bos@103 226 Having created two different versions of the file, we'll set up an
bos@103 227 environment suitable for running our merge.
bos@103 228 \interaction{tour-merge-conflict.pull}
bos@103 229
bos@103 230 In this example, I won't use Mercurial's normal \command{hgmerge}
bos@103 231 program to do the merge, because it would drop my nice automated
bos@103 232 example-running tool into a graphical user interface. Instead, I'll
bos@103 233 set \envar{HGMERGE} to tell Mercurial to use the non-interactive
bos@103 234 \command{merge} command. This is bundled with many Unix-like systems.
bos@103 235 If you're following this example on your computer, don't bother
bos@103 236 setting \envar{HGMERGE}.
bos@103 237 \interaction{tour-merge-conflict.merge}
bos@103 238 Because \command{merge} can't resolve the conflicting changes, it
bos@103 239 leaves \emph{merge markers} inside the file that has conflicts,
bos@103 240 indicating which lines have conflicts, and whether they came from our
bos@103 241 version of the file or theirs.
bos@103 242
bos@103 243 Mercurial can tell from the way \command{merge} exits that it wasn't
bos@103 244 able to merge successfully, so it tells us what commands we'll need to
bos@103 245 run if we want to redo the merging operation. This could be useful
bos@103 246 if, for example, we were running a graphical merge tool and quit
bos@103 247 because we were confused or realised we had made a mistake.
bos@103 248
bos@103 249 If automatic or manual merges fail, there's nothing to prevent us from
bos@103 250 ``fixing up'' the affected files ourselves, and committing the results
bos@103 251 of our merge:
bos@103 252 \interaction{tour-merge-conflict.commit}
bos@103 253
bos@224 254 \section{Simplifying the pull-merge-commit sequence}
bos@224 255 \label{sec:tour-merge:fetch}
bos@102 256
bos@102 257 The process of merging changes as outlined above is straightforward,
bos@102 258 but requires running three commands in sequence.
bos@102 259 \begin{codesample2}
bos@102 260 hg pull
bos@102 261 hg merge
bos@102 262 hg commit -m 'Merged remote changes'
bos@102 263 \end{codesample2}
bos@103 264 In the case of the final commit, you also need to enter a commit
bos@103 265 message, which is almost always going to be a piece of uninteresting
bos@103 266 ``boilerplate'' text.
bos@102 267
bos@102 268 It would be nice to reduce the number of steps needed, if this were
bos@102 269 possible. Indeed, Mercurial is distributed with an extension called
bos@102 270 \hgext{fetch} that does just this.
bos@102 271
bos@102 272 Mercurial provides a flexible extension mechanism that lets people
bos@102 273 extend its functionality, while keeping the core of Mercurial small
bos@102 274 and easy to deal with. Some extensions add new commands that you can
bos@102 275 use from the command line, while others work ``behind the scenes,''
bos@102 276 for example adding capabilities to the server.
bos@102 277
bos@102 278 The \hgext{fetch} extension adds a new command called, not
bos@102 279 surprisingly, \hgcmd{fetch}. This extension acts as a combination of
bos@102 280 \hgcmd{pull}, \hgcmd{update} and \hgcmd{merge}. It begins by pulling
bos@102 281 changes from another repository into the current repository. If it
bos@102 282 finds that the changes added a new head to the repository, it begins a
bos@102 283 merge, then commits the result of the merge with an
bos@102 284 automatically-generated commit message. If no new heads were added,
bos@102 285 it updates the working directory to the new tip changeset.
bos@102 286
bos@102 287 Enabling the \hgext{fetch} extension is easy. Edit your
bos@102 288 \sfilename{.hgrc}, and either go to the \rcsection{extensions} section
bos@102 289 or create an \rcsection{extensions} section. Then add a line that
bos@102 290 simply reads ``\Verb+fetch +''.
bos@102 291 \begin{codesample2}
bos@102 292 [extensions]
bos@102 293 fetch =
bos@102 294 \end{codesample2}
bos@102 295 (Normally, on the right-hand side of the ``\texttt{=}'' would appear
bos@102 296 the location of the extension, but since the \hgext{fetch} extension
bos@102 297 is in the standard distribution, Mercurial knows where to search for
bos@102 298 it.)
bos@102 299
bos@84 300 %%% Local Variables:
bos@84 301 %%% mode: latex
bos@84 302 %%% TeX-master: "00book"
bos@84 303 %%% End: