hgbook

view fr/tour-merge.tex @ 962:bac1c207c76d

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