hgbook

view fr/tour-merge.tex @ 959:b3cb66d935cf

Finished tour-merge.tex
author Romain PELISSE <belaran@gmail.com>
date Mon Feb 23 23:53:18 2009 +0100 (2009-02-23)
parents 2cd5d582c956
children bac1c207c76d
line source
1 \chapter{Un rapide tour de Mercurial: fusionner les travaux}
2 \label{chap:tour-merge}
4 Nous avons maintenons é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 travail 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ée 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 que je dois réaliser,
28 Mercurial la rend facile. Étudions ensemble le déroulement des opérations.
29 Nous commencerons par faire un clone de encore un autre dépôt (vous voyez
30 comment 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 oral l'a imposée.} 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érer 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éro de révision lorsque l'on discute d'un \textit{changeset}.) Vous
81 pouvez voir les \texit{heads} présente 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 de 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 effectuer une fusion, \hgcmd{parents} vous
114 affichera deux parents, avant que vous n'exécuter 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és 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 d'un nouveau \textit{changeset}.
129 \section{Fusionner les modifications en conflit}
131 La plupart des fusions sont assez simple à réaliser, mais parfois
132 vous vous trouverez à fusionner des fichiers où la modification touche
133 la même portion de code, au sein d'un même fichier. À moins que ces
134 modification ne soient identiques, ceci aboutira à un \emph{conflit},
135 et vous devrez décider comment réconcilier les différentes modifications
136 dans un tout cohérent.
138 \begin{figure}[ht]
139 \centering
140 \grafix{tour-merge-conflict}
141 \caption{Modifications conflictuelles dans un document}
142 \label{fig:tour-merge:conflict}
143 \end{figure}
145 La figure~\ref{fig:tour-merge:conflict} illustre un cas de modifications
146 conflictuelles dans un document. Nous avons commencé avec une version simple
147 de ce fichier, puis nous avons ajoutés des modifications, pendant que
148 quelqu'un d'autre modifie le même texte. Notre tâche dans la résolution
149 du conflit est de décider à quoi le fichier devrait ressembler.
151 Mercurial n'a pas de mécanisme interne pour gérer les conflits.
152 À la place, il exécute un programme externe appelé \command{hgmerge}.
153 Il s'agit d'un script shell qui est embarqué par Mercurial, vous
154 pouvez le modifier si vous le voulez. Ce qu'il fait par défaut est
155 d'essayer de trouver un des différents outils de fusion qui seront
156 probablement installé sur le système. Il commence par les outils
157 totalement automatique, et si ils échouent (parce que la résolution
158 du conflit nécessite une intervention humaine) ou si ils sont absents,
159 le script tente d'exécuter certains outils graphiques de fusion.
161 Il est aussi possible de demander à Mercurial d'exécuter un autre
162 programme ou un autre script au lieu de la commande \command{hgmerge},
163 en définissant la variable d'environnement \envar{HGMERGE} avec le nom
164 du programme de votre choix.
166 \subsection{Utiliser un outil graphique de fusion}
168 Mon outil de fusion préféré est \command{kdiff3}, que j'utilise ici
169 pour illustré les fonctionnalités classiques des outils graphiques
170 de fusion. Vous pouvez voir une capture d'écran de l'utilisation de
171 \command{kdiff3} dans la figure~\ref{fig:tour-merge:kdiff3}. Cet outil
172 effectue une \emph{fusion \textit{three-way}}, car il y a trois différentes
173 versions du fichier qui nous intéresse. Le fichier découpe la partie
174 supérieure de la fenêtre en trois panneaux:
176 \begin{itemize}
177 \item A gauche on la version de \emph{base} du fichier, soit ~la plus
178 récente version des deux versions qu'on souhaite fusionner.
179 \item Au centre, il y a ``notre'' version du fichier, avec le contenu
180 que nous avons modifié.
181 \item Sur la droite, on trouve ``leur'' version du fichier, celui qui qui
182 contient le \textit{changeset} que nous souhaitons intégré.
183 \end{itemize}
185 Dans le panneau en dessous, on trouve le \emph{résultat} actuel de notre
186 fusion. Notre tâche consiste donc à remplacement tout les textes en rouges,
187 qui indiquent des conflits non résolus, avec un fusion manuel et pertinente
188 de ``notre'' version et de la ``leur''.
190 Tout les quatre panneaux sont \emph{accrochés ensemble}, si nous déroulons
191 les ascenseurs verticalement ou horizontalement dans chacun d'entre eux, les
192 autres sont mise à jours avec la section correspondantes dans leurs fichiers.
194 \begin{figure}[ht]
195 \centering
196 \grafix{kdiff3}
197 \caption{Utilisation de \command{kdiff3} pour fusionner différents versions
198 d'un fichier.}
199 \label{fig:tour-merge:kdiff3}
200 \end{figure}
202 Pour chaque portion de fichier posant problème, nous pouvons choisir
203 de résoudre le le conflit en utilisant en utilisant une combinaison
204 de texte depuis la version de base, la notre, ou la leur. Nous pouvons
205 aussi éditer manuellement les fichiers à tous moments, si c'est
206 nécessaire.
208 Il y a \emph{beaucoup} d'outils de fusion disponibles, bien trop pour
209 en parler de tous ici. Leurs disponibilités varient selon les plate formes
210 ainsi que leurs avantages et inconvénients. La plupart sont optimisé pour
211 la fusion de fichier contenant un texte plat, certains sont spécialisé
212 dans un format de fichier précis (généralement XML).
214 \subsection{A worked example} %TODO: Find a translation for this !
216 Dans cet exemple, nous allons reproduire la modification de l'historique
217 du fichier de la figure~\ref{fig:tour-merge:conflict} ci dessus. Commençons
218 par créer un dépôt avec une version de base de notre document.
220 \interaction{tour-merge-conflict.wife}
221 Créons un clone de ce dépôt et faisons une modification dans le fichier.
222 \interaction{tour-merge-conflict.cousin}
223 Et un autre clone, pour simuler que quelqu'un d'autre effectuer une
224 modification sur le fichier. (Ceci pour suggérer qu'il n'est pas rare
225 de devoir effectuer des \textit{merge} avec vos propres travaux quand
226 vous isoler les tâches dans des dépôts distincts. En effet, vous
227 aurez alors à trouver et résoudre certains conflits).
228 \interaction{tour-merge-conflict.son}
229 Maintenant que ces deux versions différentes du même fichier sont
230 créées, nous allons configurer l'environnement approprié pour exécuter
231 notre \textit{merge}.
232 \interaction{tour-merge-conflict.pull}
234 Dans cette exemple, je n'utiliserais pas la commande Mercurial
235 habituelle \command{hgmerge} pour effectuer le \textit{merge},
236 car il me faudrait abandonner ce joli petit exemple automatisé
237 pour utiliser un outil graphique. À la place, je vais définir
238 la variable d'environnement \envar{HGMERGE} pour indiquer à
239 Mercurial d'utiliser la commande non-interactive \command{merge}.
240 Cette dernière est embarqué par de nombreux systèmes ``à la Unix''.
241 Si vous exécuter cet exemple depuis votre ordinateur, ne vous
242 occupez pas de définir \envar{HGMERGE}.
243 \interaction{tour-merge-conflict.merge}
244 Parce que \command{merge} ne peut pas résoudre les modifications
245 conflictuelles, il laisse des \emph{marqueurs de différences}
246 \footnote{NdT: Oui, je traduis \textit{merge markers} par un sens
247 inverse en Français, mais je pense vraiment que c'est plus clair
248 comme ça...} à l'intérieur du fichier qui a des conflits, indiquant
249 clairement quelles lignes sont en conflits, et si elles viennent de
250 notre fichier ou du fichier externe.
252 Mercurial peut distinguer, à la manière dont la commande \command{merge}
253 se termine, qu'elle n'a pas été capable d'effectuer le \textit{merge},
254 alors il nous indique qu'il faut devons effectuer de nouveau cette
255 opération. Ceci peut être très utile si, par exemple, nous exécutons un
256 outil graphique de fusion et que nous le quittons sans se rendre compte
257 qu'il reste des conflits ou simplement par erreur.
259 Si le \textit{merge} automatique ou manuel échoue, il n'y a rien pour
260 nous empêcher de ``corriger le tir'' en modifiant nous même les fichiers,
261 et enfin effectuer le \textit{commit} du fichier:
262 \interaction{tour-merge-conflict.commit}
264 \section{Simplifier l'enchaînement de \textit{pull-merge-commit} }
265 \label{sec:tour-merge:fetch}
267 Le processus de fusion des modifications, comme indiqué ci dessus,
268 est simple, mais il requiert d'exécuter 3 commandes de suite.
269 \begin{codesample2}
270 hg pull
271 hg merge
272 hg commit -m 'Merged remote changes'
273 \end{codesample2}
274 Dans le cas d'un \textit{commit} final, vous avez aussi besoin
275 de saisir un message, qui sera presque systématiquemetn un texte
276 sans grand interêt, juste pour mentionner qu'un \textit{merge} a
277 eu lieu.
279 Il serait agréable de pouvoir réduire le nombre d'étape nécessaire.
280 En effet, Mercurial est distribué avec une extension nommée \hg{fetch}
281 qui le permet.
283 Mercurial fournit un méchanisme flexible d'extension qui permet à
284 quiquonque d'ajouter des fonctionnalités, tout en conservant le
285 coeur de Mercurial relativement petit et facile à maintenir. Quelques
286 extensions ajoutent des nouvelles commandes que vous pouvez utiliser
287 depuis votre terminal, alors que d'autres opèrent ``dans les coulisses'',
288 pour ajouter par exemple des fonctionnalités au server.
290 L'extension \hgext{fetch} ajoute une nouvelle commande appelée, sans
291 surprise, \hgcmd{fetch}. Cette extension agit comme une combinaison
292 de \hgcmd{pull}, \hgupdate{update} et \hgcmd{merge}. Elle commence
293 par faire un \textit{pull} des modifications depuis un autre dépôt dans
294 le dépôt local. Si elle trouve des modifications ajoutés à la \textit{head}
295 du dépôt, elle commencera à effectuer le \textit{merge}, puis elle
296 déclenchera le \textit{commit} du résultat avec un message généré
297 automatiquement. Si aucune nouvell \textit{head} n'est ajouté elle
298 met à jour l'espace de travail avec le nouveau \textit{tip}.
300 Activé l'extension \hgext{fetch} est très facile. Ouvrez le fichier
301 \sfilename{.hgrc}, et, soit allez dans la section \rcsection{extensions}
302 ou créer une section \rcsection{extensions} si elle absente. Ensuite,
303 ajoutée une ligne qui contient simplement ``\Verb+fetch +''.
304 \begin{codesample2}
305 [extensions]
306 fetch =
307 \end{codesample2}
308 (Normalement, à droite du signe ``\texttt{=}'' on verrait apparaître
309 l'adresse de l'extension sur le système, mais comme \hgext{fetch} est
310 une extension distribué avec Mercurial, ce dernier sait où la
311 retrouver.)
313 %%% Local Variables:
314 %%% mode: latex
315 %%% TeX-master: "00book"
316 %%% End: