hgbook

view fr/ch04-concepts.xml @ 1001:669ae1a09e46

French translation : ch04-concepts translated
author Frédéric Bouquet <youshe.jaalon@gmail.com>
date Mon Sep 14 01:18:56 2009 +0200 (2009-09-14)
parents 71dbda516572
children df8efd83cfc9
line source
1 <!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
3 <chapter id="chap:concepts">
4 <?dbhtml filename="behind-the-scenes.html"?>
5 <title>Derrière le décor</title>
7 <para id="x_2e8">À la différence de beaucoup d'outils de gestion de versions,
8 les concepts sur lesquels se base Mercurial sont assez simples pour
9 qu'il soit facile de comprendre comment le logiciel fonctionne.
10 Bien que leur connaissance ne soit pas nécéssaire, je trouve utile
11 d'avoir un <quote>modèle mental</quote> de ce qui se passe.</para>
13 <para id="x_2e9">En effet, cette compréhension m'apporte la confiance que
14 Mercurial a été développé avec soin pour être à la fois
15 <emphasis>sûr</emphasis> et <emphasis>efficace</emphasis>. De surcroît,
16 si il m'est facile de garder en tête ce que le logiciel fait lorsque
17 j'accompli des tâches de révision, j'aurai moins de risques d'être
18 surpris par son comportement.</para>
20 <para id="x_2ea">Dans ce chapitre, nous décrirons tout d'abord les concepts
21 essentiels de l'architecture de Mercurial, pour ensuite discuter quelques
22 uns des détails intéressants de son implémentation.</para>
24 <sect1>
25 <title>Conservation de l'historique sous Mercurial</title>
26 <sect2>
27 <title>Suivi de l'historique pour un seul fichier</title>
29 <para id="x_2eb">Lorsque Mercurial effectue un suivi des modifications
30 faites à un fichier, il conserve l'historique pour ce fichier dans un
31 <emphasis>filelog</emphasis> sous forme de métadonnées. Chaque entrée
32 dans le filelog contient assez d'informations pour reconstituer une
33 révision du fichier correspondant. Les filelogs sont des fichiers
34 stockés dans le répertoire <filename role="special"
35 class="directory">.hg/store/data</filename>. Un filelog contient
36 des informations de deux types: les données de révision, et un index
37 pour permettre à Mercurial une recherche efficace d'une révision
38 donnée.</para>
40 <para id="x_2ec">Lorsqu'un fichier devient trop gros ou a un long
41 historique, son filelog se voit stocker dans un fichier de données
42 (avec un suffixe <quote><literal>.d</literal></quote>) et un fichier
43 index (avec un suffixe<quote><literal>.i</literal></quote>)
44 distincts. La relation entre un fichier dans le répertoire de travail
45 et le filelog couvrant le suivi de son historique dans le dépôt est
46 illustré à la figure <xref linkend="fig:concepts:filelog"/>.</para>
48 <figure id="fig:concepts:filelog">
49 <title>Relations entre les fichiers dans le répertoire de travail et
50 leurs filelogs dans le dépôt</title>
51 <mediaobject> <imageobject><imagedata
52 fileref="figs/filelog.png"/></imageobject>
53 <textobject><phrase>XXX add text</phrase></textobject>
54 </mediaobject> </figure>
56 </sect2>
57 <sect2>
58 <title>Gestion des fichiers suivis</title>
60 <para id="x_2ee">Mercurial a recours à une structure nommée
61 <emphasis>manifest</emphasis> pour rassembler les informations sur
62 les fichiers dont il gère le suivi. Chaque entrée dans ce manifest
63 contient des informations sur les fichiers présents dans une révision
64 donnée. Une entrée enregistre la liste des fichiers faisant partie de la
65 révision, la version de chaque fichier, et quelques autres
66 métadonnées sur ces fichiers.</para>
68 </sect2>
69 <sect2>
70 <title>Enregistrer les informations des changeset</title>
72 <para id="x_2ef">Le <emphasis>changelog</emphasis> contient les
73 informations sur chaque changeset. Chaque révision enregistre qui a
74 committé un changement, le commentaire du changeset, d'autres
75 morceaux d'information relatives au changeset et la révision du
76 manifest à utiliser.</para>
78 </sect2>
79 <sect2>
80 <title>Relations entre les révisions</title>
82 <para id="x_2f0">A l'intérieur d'un changelog, d'un manifest, ou d'un
83 filelog, chaque révision enregistre un pointeur vers son parent
84 immédiat (ou à ses deux parents s'il s'agit d'une révision
85 correspondant à une fusion (merge)). Comme mentionné plus haut, il y
86 a aussi des relations entre les révisions <emphasis>à
87 travers</emphasis> ces structures, qui sont de nature
88 hiérarchique.</para>
90 <para id="x_2f1">Pour chaque changeset dans un dépôt, il y a exactement
91 une révision stockée dans le changelog. Chaque révision du changelog
92 contient un pointeur vers une unique révision du manifest. Une
93 révision du manifeste garde un pointeur vers une unique révision pour
94 chaque filelog suivi lorsque le changeset est créé. Ces relations
95 sont illustrées dans <xref linkend="fig:concepts:metadata"/>.</para>
97 <figure id="fig:concepts:metadata">
98 <title>Metadata relationships</title>
99 <mediaobject> <imageobject><imagedata
100 fileref="figs/metadata.png"/></imageobject>
101 <textobject><phrase>XXX add text</phrase></textobject>
102 </mediaobject>
103 </figure>
105 <para id="x_2f3">Comme l'illustration le monde, il
106 <emphasis>n'</emphasis>y a <emphasis>pas</emphasis> de relation
107 <quote>un à un</quote> entre les révisions dans un changelog,
108 manifest ou filelog. Si un fichier que Mercurial suit n'a pas changé
109 entre deux changesets, l'entrée pour ce fichier dans les deux
110 révisions du manifest pointera vers la même révision de son filelog
111 <footnote> <para id="x_725">Il est possible (bien qu'inhabituel)
112 qu'un manifest reste le même entre deux changesets, auquel cas
113 l'entrée du changelog pour ces changesets pointera vers la même
114 révision du manifest.</para>
115 </footnote>.</para>
117 </sect2>
118 </sect1>
119 <sect1>
120 <title>Stockage sûr et efficace</title>
122 <para id="x_2f4">Les fondements des changelogs, des manifests et des
123 filelogs sont fournis par une unique structure appelée le
124 <emphasis>revlog</emphasis>.</para>
126 <sect2>
127 <title>stockage efficace</title>
129 <para id="x_2f5">Le revlog fournit un stockage efficace des révision en
130 utilisant un mécanisme <emphasis>delta</emphasis>. A lieu de stocker
131 une copie complète d'un fichier à chaque révision, il stocke les
132 changements requis pour transformer une révision plus ancienne en la
133 nouvelle révision. Pour plusieurs type de données, ces deltas sont
134 typiquement une fraction de pourcentage de la taille de la copie
135 complète d'un fichier.</para>
137 <para id="x_2f6">Certains systèmes de gestion de révisions obselètes
138 peuvent seulement travailler avec les deltas de fichiers texte. Il
139 doivent d'ailleurs stocker les fichiers binaires comme des images
140 complètes ou encodées avec une représentation texte, chacune de ces
141 approches étant gaspilleuse. Mercurial peut traiter les deltas de
142 fichiers avec du contenu binaire arbitraire ; il n'a pas besoin de
143 traiter spécialement du texte.</para>
145 </sect2>
146 <sect2 id="sec:concepts:txn">
147 <title>Opérations sûres</title>
149 <para id="x_2f7">Mercurial <emphasis>empile</emphasis> toujours les
150 données à la fin d'un fichier revlog. Il ne modifie jamais la section
151 d'un fichier après qu'il l'ait écrite. C'est à la foit plus robuste
152 et efficace que les schémas qui ont besoin de modifier ou réécrire
153 les données.</para>
155 <para id="x_2f8">De plus, Mercurial traite chaque écriture comme une
156 partie d'une <emphasis>transaction</emphasis> qui peut comprendre
157 plusieurs fichiers. Une transaction est <emphasis>atomique</emphasis>
158 : spot la transaction entière réussit et ses effets sont tous
159 visibles aux lecteurs en une étape, soit la totalité est annulée.
160 Cette garantie de l'atomicité signifie que si vous exécutez deux
161 copies de Mercurial, où une lit les données et l'autre les écrit, le
162 lecteur ne verra jamais un résultat partiellement écrit qui pourrait
163 le perturber.</para>
165 <para id="x_2f9">Le fait que Mercurial ne fasse qu'ajouter aux fichiers
166 fait qu'il est facile de fournir cette garantie de transaction. Plus
167 les choses sont faites simplement comme ça, plus vous pouvez être
168 rassurés qu'elles sont bien faites.</para>
170 </sect2>
171 <sect2>
172 <title>Récupération rapide</title>
174 <para id="x_2fa">Mercurial évite habillement un piège commun à tous les
175 vieux systèmes de gestion de révisions : le problème de la
176 <emphasis>récupération inefficace</emphasis> La plupart des systèmes
177 de gestion de révisions stockent le contenu d'une révision comme une
178 série incrémentale de modifications faites à un
179 <quote>snapshot</quote>. (Certains basent le snapshot sur la plus
180 vieille révision, d'autres sur la plus récente.) Pour reconstruire
181 une révision spécifique, vous devez d'abord lire le snapshot, et
182 ensuite toutes les révisions entre le snapshot et votre révision
183 cible. Plus vous avez d'historique accumulé dans un fichier, plus de
184 révisions vous avez à lire, d'où la longueur que cela prend à
185 reconstruire une révision particulière.</para>
187 <figure id="fig:concepts:snapshot">
188 <title>Snapshot d'un revlog, avec des deltas incrémentaux</title>
189 <mediaobject> <imageobject><imagedata
190 fileref="figs/snapshot.png"/></imageobject>
191 <textobject><phrase>XXX add text</phrase></textobject>
192 </mediaobject>
193 </figure>
195 <para id="x_2fc">L'inovation que Mercurial apporte à ce problème est
196 simple mais effective. Une fois que la quantité cumulée de deltas
197 d'informations stockées depuis le dernier snapshot excède un seuil
198 fixé, il stock un nouveau snapshot (compréssé biensûr), plutôt qu'un
199 nouveau delta. Ceci rend possible la reconstruction de
200 <emphasis>toute</emphasis> révision d'un fichier rapidement. Cette
201 approche fonctionne si bien que depuis, elle a été copiée par
202 plusieurs autres systèmes de gestion de révisions.</para>
204 <para id="x_2fd"><xref linkend="fig:concepts:snapshot"/> illustre
205 l'idée. Dans une entrée d'un fichier d'index de revlog, Mercurial
206 stock l'intervale des entrées depuis le fichier de données qu'il doit
207 lire pour reconstruire une révision particulière.</para>
209 <sect3>
210 <title>En amont : l'influence de la compression vidéo</title>
212 <para id="x_2fe">Si vous êtes familiés de la compression vidéo ou
213 avez déjà regardé un programme TV par cable ou par un service
214 satellite, vous devez savoir que la plupart des schémas de
215 compression vidéo stockent chaque frame de vidéo comme un delta vis
216 à vis de la frame précédente.</para>
218 <para id="x_2ff">Mercurial emprunte cette idée pour rendre possible
219 la reconstruction d'une révision à partir d'un snapshot et d'un
220 petit nombre de deltas.</para>
222 </sect3>
223 </sect2>
224 <sect2>
225 <title>Identification et intégrité forte</title>
227 <para id="x_300">Avec les deltas ou l'information du snapshot, une
228 entrée d'un revlog contient un hash cryptographique des données qu'il
229 représente. Ceci fait qu'il est difficile de construire les données
230 d'une révision, mais facile de détecter une corruption
231 accidentelle.</para>
233 <para id="x_301">Les hash fournissent plus qu'un bon moyen de
234 vérification contre la corruption ; il sont aussi utilisés comme
235 identifiants pour les révisions. Le hash d'identification d'un
236 changeset que vous voyez comme utilisateur final proviennent des
237 révisions du changelog. Bien que les filelogs et le manifest
238 utilisent aussi des hash, Mercurial ne les utilise qu'en arrière
239 plan.</para>
241 <para id="x_302">Mercurial vérifie que les hash sont corrects lorsqu'il
242 récupère les révisions de fichiers et lorsqu'il récupère (pull) les
243 changements d'un autre dépôt. S'il rencontre un problème d'intégrité,
244 il se pleindra et arrêtera tout ce qu'il est en train de faire.</para>
246 <para id="x_303">En plus de l'effet qu'il a sur l'efficacité des
247 récupérations, l'utilisation de Mercurial de snapshots périodiques
248 fait qu'il est plus robuste contre la corruption partielle de
249 données. Si un revlog devient partiellement corrompu à cause d'une
250 erreur matérielle ou d'un bug système, il est souvent possible de
251 reconstruire certaines ou la plupart des révisions à partir des
252 sections non corrompues du revlog, avant et après la section
253 corrompue. Ceci ne serait pas possible à partir d'un modèle de
254 stockage delta seul.</para>
255 </sect2>
256 </sect1>
258 <sect1>
259 <title>Historique des révisions, branches et fusions (merge)</title>
261 <para id="x_304">Chaque entrée dans un revlog Mercurial connaît
262 l'identité de l'ancètre immédiat de la révision, habituellement référé
263 comme son <emphasis>parent</emphasis>. En fait, une révision contient
264 de la place pour non pas un parent, mais deux. Mercurial utilise un
265 hash spécial, appelé le <quote>null ID</quote> pour représenter l'idée
266 qu'<quote>il n'y a pas de parent ici</quote>. Ce hash est simplement
267 une chaîne de zéros.</para>
269 <para id="x_305">Dans <xref linkend="fig:concepts:revlog"/>, vous pouvez
270 voir un exemple de la structure conceptuelle d'un revlog. Les filelogs,
271 manifests et changelogs ont tous cette même structure ; ils difèrent
272 simplement dans le type de donnée stockée dans chaque delta ou
273 snapshot.</para>
275 <para id="x_306">La première révision d'un revlog (au bas de l'image) a
276 le null ID dans chacune de ses cases parent. Pour une révision
277 <quote>normale</quote>, sa première case parent contient l'ID de sa
278 révision parent et la seconde contient le null ID, indiquant que cette
279 révision n'a qu'un seul vrai parent. Si deux révisions ont le même
280 parent, il s'agit de branches. Une révision qui représente une fusion
281 (merge) entre deux branches a deux identifiants de révision normaux
282 dans ses cases parents.</para>
284 <figure id="fig:concepts:revlog">
285 <title>The conceptual structure of a revlog</title>
286 <mediaobject> <imageobject><imagedata
287 fileref="figs/revlog.png"/></imageobject> <textobject><phrase>XXX
288 add text</phrase></textobject>
289 </mediaobject>
290 </figure>
292 </sect1>
293 <sect1>
294 <title>Le répertoire de travail</title>
296 <para id="x_307">Dans un répertoire de travail, Mercurial stock une image
297 des fichiers du dépôt à un changeset particulier.</para>
299 <para id="x_308">Le répertoire de travail <quote>sait</quote> quel
300 changeset il contient. Lorsque vous mettez à jour (update) le
301 répertoire de travail à un certain changeset, Mercurial regarde la
302 révision appropriée du manifest pour trouver quels fichier il suivait
303 au moment où le changeset a été committé, et quelle révision de chaque
304 fichier était alors courante. Il recrée ensuite une copie de chacun de
305 ces fichiers, avec le même contenu qu'ils avaient lorsque le changeset
306 a été committé.</para>
308 <para id="x_309">La structure spéciale <emphasis>dirstate</emphasis>
309 contient la connaissance de Mercurial sur le répertoire de travail.
310 Elle est maintenue par un fichier appelé
311 <filename>.hg/dirstate</filename> dans un dépôt. Les détails du
312 dirstate sont le changeset vers lequel le répertoire de travail se met
313 à jour (update), et tous les fichiers que Mercurial suit dans le
314 répertoire de travail. Il permet aussi à Mercurial se connaître
315 rapidement les fichiers modifiés, en enregistrant leurs heures de
316 dernière modification et leur taille.</para>
318 <para id="x_30a">Puisqu'une révision de revlog a des emplacements pour
319 deux parents et peut représenter aussi bien une révision normale (avec
320 un parent) ou une fusion de deux révisions anciennes, le dirstate a des
321 emplacements pour deux parents. Lorsque vous utilisez la commande
322 <command role="hg-cmd">hg update</command>, le changeset que vous
323 mettez à jour est stocké dans l'emplacement du <quote>premier
324 parent</quote>, et le null ID l'est dans le second. Lorsque vous
325 utilisez la commande <command role="hg-cmd">hg merge</command> avec un
326 autre changeset, le premier parent reste inchangé, et le second est
327 rempli avec le changeset à partir duquel vous êtes en train de
328 fusionner. La commande <command role="hg-cmd">hg parents</command> vous
329 donne les parents du dirstate.</para>
331 <sect2>
332 <title>Que se passe-t-il lorsque vous committez</title>
334 <para id="x_30b">Le dirstate stock les informations sur les parents
335 pour plusqu'un simple livre de stockage. Mercurial utilise les
336 parents du distate comme <emphasis>les parents d'un nouveau
337 changeset</emphasis> lorsque vous committez.</para>
339 <figure id="fig:concepts:wdir">
340 <title>Le répertoire de travail peut avoir deux parents</title>
341 <mediaobject>
342 <imageobject><imagedata fileref="figs/wdir.png"/></imageobject>
343 <textobject><phrase>XXX add text</phrase></textobject></mediaobject>
344 </figure>
346 <para id="x_30d"><xref linkend="fig:concepts:wdir"/> montre l'état
347 normal d'un répertoire de travail, où il n'y a qu'un seul changeset
348 comme parent. Ce changeset est le <emphasis>tip</emphasis>, le
349 changeset le plus récent dans le dépôt n'a pas d'enfant.</para>
351 <figure id="fig:concepts:wdir-after-commit">
352 <title>Le répertoire de travail gagne de nouveaux parents après un
353 commit</title>
354 <mediaobject>
355 <imageobject><imagedata
356 fileref="figs/wdir-after-commit.png"/></imageobject>
357 <textobject><phrase>XXX add text</phrase></textobject>
358 </mediaobject>
359 </figure>
361 <para id="x_30f">Il est utile de penser du répertoire de travail qu'il
362 est <quote>le changeset que je vais committer</quote>. Chaque fichier
363 que vous dites à mercurial d'ajouter, de supprimer, de renommer ou de
364 copier va être reflété dasn ce changeset, tout comme les
365 modifications de n'importe quel fichier que Mercurial est déjà en
366 train de suite ; le nouveau changeset aura les mêmes parents que le
367 répertoire de travail.</para>
369 <para id="x_310">Après un commit, Mercurial va mettre à jour les
370 parents du répertoire de travail, ainsi, le premier parents est l'ID
371 du nouveau changeset, et le second, le nullID. Ceci est illustré dans
372 <xref linkend="fig:concepts:wdir-after-commit"/>. Mercurial ne touche
373 à aucun des fichiers du répertoire de travail lorsque vous committez
374 ; il modifie simplement le dirstate pour noter ses nouveaux
375 parents.</para>
377 </sect2>
378 <sect2>
379 <title>Création d'une nouvelle <quote>head</quote></title>
381 <para id="x_311">Il est parfaitement normal de faire un update du
382 répertoire de travail à un changeset autre que le tip courant. Par
383 exemple, vous pourriez vouloir savoir ce à quoi votre projet
384 ressemblait le dernier Mardi, ou regarder le changeset qui a
385 introduit un bug. Dans des cas comme ça, la chose naturelle à faire
386 est de faire un update du répertoire de travail au changeset qui vous
387 intéresse, et ensuite d'en examiner les fichiers pour regarder leurs
388 contenus comme ils l'étaient lorsque vous avez commité ce changeset.
389 L'effet de ceci est montré dans <xref
390 linkend="fig:concepts:wdir-pre-branch"/>.</para>
392 <figure id="fig:concepts:wdir-pre-branch">
393 <title>Le répertoire de travail, "updaté" pour un changeset plus
394 ancien</title>
395 <mediaobject> <imageobject><imagedata
396 fileref="figs/wdir-pre-branch.png"/></imageobject>
397 <textobject><phrase>XXX add text</phrase></textobject>
398 </mediaobject>
399 </figure>
401 <para id="x_313">En ayant fait un update du répertoire de travail vers
402 un changeset plus ancien, qu'est-ce qu'il se passe si vous faites des
403 changements et ensuite committez ? Mercurial se comporte comme je
404 l'ai fait remarqué plus haut. Les parents du répertoire de travail
405 deviennent les parents du nouveau changeset. Ce nouveau changeset n'a
406 pas d'enfant, donc il devient le nouveau tip. Le dépôt contient
407 maintenant deux changesets qui n'ont pas d'enfant ; on appelle ceci
408 des <emphasis>heads</emphasis>. Vous pouvez voir la structire que
409 cela crée dans <xref linkend="fig:concepts:wdir-branch"/>.</para>
411 <figure id="fig:concepts:wdir-branch">
412 <title>Après un commit fait pendant la synchronisation avec un ancien
413 changeset</title>
414 <mediaobject> <imageobject><imagedata
415 fileref="figs/wdir-branch.png"/></imageobject>
416 <textobject><phrase>XXX add text</phrase></textobject>
417 </mediaobject>
418 </figure>
420 <note>
421 <para id="x_315">Si vous êtes nouveau à Mercurial, vous devez garder
422 à l'esprit une <quote>erreur</quote> commune, qui est d'utiliser la
423 commande <command role="hg-cmd">hg pull</command> sans aucune
424 option. Par défaut, la commande <command role="hg-cmd">hg
425 pull</command> <emphasis>ne fait pas</emphasis> d'update sur le
426 répertoire de travail, ainsi, vous allez récupérer les nouveaux
427 changesets dans votre dépôt, mais le répertoire de travail va
428 rester synchroniser au même changeset qu'il l'était avant le pull.
429 Si vous faites des changements et committez ensuite, vous allez
430 créer une nouvelle head puisque votre répertoire de travail n'est
431 pas synchronisé à ce que le tip actuel est. Pour combiner les
432 opérations d'un pull suivi d'un update, exécutez run <command>hg
433 pull -u</command>.</para>
435 <para id="x_316">Je place le mot <quote>erreur</quote> entre
436 guillemets parce que tous ce dont vous avez besoin de faire pour
437 rectifier la situation où vous avez créé une nouvelle head par
438 accident est un <command role="hg-cmd">hg merge</command> suivi
439 d'un <command role="hg-cmd">hg commit</command>. En d'autres mots,
440 ceci n'a presque jamais de conséquences négatives ; il s'agit juste
441 d'une surprise pour les nouveaux arrivants. Je discuterai d'autres
442 moyens d'éviter ce comportement, et pourquoi Mercurial agit de
443 cette façon surprenante plus tard.</para>
444 </note>
446 </sect2>
447 <sect2>
448 <title>Fusionner (merge) les changements</title>
450 <para id="x_317">Lorsque vous exécutez la commande <command
451 role="hg-cmd">hg merge</command>, Mercurial laisse le premier
452 parent du répertoire de travail inchangé et fixe le second au
453 changeset avec lequel vous fusionnez (merge), comme montré dans <xref
454 linkend="fig:concepts:wdir-merge"/>.</para>
456 <figure id="fig:concepts:wdir-merge">
457 <title>Fusionner (merge) deux heads</title>
458 <mediaobject>
459 <imageobject> <imagedata fileref="figs/wdir-merge.png"/>
460 </imageobject> <textobject><phrase>XXX add text</phrase></textobject>
461 </mediaobject>
462 </figure>
464 <para id="x_319">Mercurial doit aussi modifier le répertoire de
465 travail pour fusionner les fichiers gérés dans les deux changesets.
466 Un peu simplifié, le processus de fusion fonctionne comme ça : pour
467 chaque fichier dans le manifest de chaque changeset.</para>
469 <itemizedlist>
470 <listitem><para id="x_31a">Si aucun changeset n'a modifié un fichier,
471 ne rien faire avec ce fichier.</para> </listitem>
472 <listitem><para id="x_31b">Si un changeset a modifié un fichier et
473 que l'autre ne l'a pas fait, créer une copie modifiée du fichier
474 dans le répertoire de travail.</para> </listitem>
475 <listitem><para id="x_31c">Si un changeset a modifié un fichier, et
476 que l'autre ne l'a pas fait (ou l'a supprimé), supprimer le
477 fichier du répertoire de travail.</para> </listitem>
478 <listitem><para id="x_31d">Si un changeset a supprimé un fichier,
479 mais que l'autre a modifié le fichier, demander à l'utilisateur
480 quoi faire : garder le fichier modifié ou le supprimer ?</para>
481 </listitem>
482 <listitem><para id="x_31e">Si chacun des chengeset a modifié un
483 fichier, invoquer le programme externe de fusion pour choisir les
484 nouveaux contenus pour le fichier fusionné. Ceci peut demander
485 des entrées de l'utilisateur.</para></listitem>
486 <listitem><para id="x_31f">Si un changeset a modifié un fichier, et
487 que l'autre a renommé ou copié le fichier, être sûr que les
488 changements suivent le nouveau nom du fichier.</para></listitem>
489 </itemizedlist>
491 <para id="x_320">Il y a plus de détails&emdash;fusionner a beaucoup de
492 cas anguleux&emdash;mais ceux-ci sont des chois plus communs qui sont
493 invoqués pendant une fusion (merge). Comme vous pouvez le voir, la
494 plupart des cas sont entièrement automatiques, et effectivement, la
495 plupart des fusions (merge) se terminent automatiquement, sans avoir
496 besoin d'entrées pour résoudre un conflit.</para>
498 <para id="x_321">Lorsque vous pensez à ce qu'il se passe lorsque vous
499 committez après un merge, une fois encore, le répertoire de travail
500 est <quote>le changeset que je suis sur le point de
501 committer</quote>. Après que la commande <command role="hg-cmd">hg
502 merge</command> ait terminé, le répertoire de travail a deux
503 parents ; ceux ci vont devenir les parents du nouveau
504 changeset.</para>
506 <para id="x_322">Mercurial vous permet d'exécuter de multiples fusions,
507 mais vous devez committer le résultat de chaque fusion individuelle
508 comme vous avancez. Ceci est nécessaire puisque Mercurial ne stock
509 que deux parents pour chaque révision et le répertoire de travail.
510 Alors qu'il serait techniquement faisble de fusionner de multiples
511 changesets en même temps, Mercurial interdit cette simplicité. Avec
512 des fusions multplus, les risques de confision utilisateur, de
513 conflits néfastes de résolutions, et faire une pagaille d'une fusion
514 grossiraient intollérablement.</para>
516 </sect2>
518 <sect2>
519 <title>Fusions et renommages</title>
521 <para id="x_69a">Un nombre surprenant de systèmes de gestion de
522 révision fait peu ou pas attention à un <emphasis>nom</emphasis> au
523 cours du temps. Par exemple, il était habituel que si un fichier
524 était renommé d'un coté de la fusion, les changements à partir de
525 l'autre coté étaient supprimés silencieusement.</para>
527 <para id="x_69b">Mercurial enregistre les metadata lorsque vous lui
528 dite d'exécuter un renommage ou une copie. Il utilise ces metadata
529 durant une fusion pour faire les bonnes choses dans le cas d'un
530 merge. Par exemple, si je renomme un fichier et que vous l'éditez
531 sans le renommer, lorsque l'on fusionne, le fichier sera renommé et
532 aura les éditions appliquées.</para>
534 </sect2>
535 </sect1>
537 <sect1>
538 <title>D'autres fonctionnalités intéressantes</title>
540 <para id="x_323">Dans les sections au dessus, j'ai tenté de mettre
541 l'accent sur certains aspects importants du design de Mercurial pour
542 illustrer l'attention particulière qui a été portée à la fiabilité et à
543 la performance.Cependant, l'attention aux détails ne s'arrête pas ici.
544 Il y a de nombreux aspects sur la construction de Mercurial que je
545 trouve personnellement intéressante. Je détaillerai quelques un d'eux
546 ici, séparément des éléments du <quote>big ticket</quote> ci dessus,
547 ainsi, si vous êtes intéressés, vous pourrez avoir une meilleure idée
548 de la quantité de pensées qu'il y a derrière un système bien
549 défini.</para>
551 <sect2>
552 <title>Compression élégante</title>
554 <para id="x_324">Lorsque cela est approprié, Mercurial stocke les
555 snapshots et deltas sous une forme compressée. Il le fait en
556 <emphasis>essayant</emphasis> toujours de compression un snapshot ou
557 un delta, mais en ne stockant la version compression que si celle ci
558 est plus petite que la version non compressée.</para>
560 <para id="x_325">Ceci signifie que Mercurial fait <quote>la bonne
561 chose</quote> lorsqu'il stocke un fichier dont la forme native est
562 compressée, comme une archive <literal>zip</literal> ou une image
563 JPEG. Lorsque ces types de fichiers sont compressés une seconde fois,
564 le fichier obtenu est habituellement plus gros que la forme
565 compressée une seule fois et Mercurial stockera alors le
566 <literal>zip</literal> ou JPEG.</para>
568 <para id="x_326">Les Deltas entre les révisions d'un fichier compressé
569 sont habituellement plus gros que les snapshots du fichier, et
570 Mercurial fait à nouveau <quote>la bonne chose</quote> dans ces cas.
571 Il trouve qu'un delta dépasse le seuil auquel il devrait stocker un
572 snapshot complet du ficheir, alors il stocke le snapshot, en gagnant
573 encore de la place en comparaison à une approche naïve delta
574 seulement.</quote>
576 <sect3>
577 <title>Recompression réseau</title>
579 <para id="x_327">Lors du stockage des révisions sur le disque,
580 Mercurial utilise l'algorithme de compression
581 <quote>deflate</quote> (le même que celui utilisé pour le format
582 d'archive populaire <literal>zip</literal>), qui est un bon
583 comprimis entre la vitesse et le taux de compression. Cependant,
584 lors de la transmission d'une révision de données par une connexion
585 réseau, Mercurial décompresse les données de révision
586 compressées.</para>
588 <para id="x_328">Si la connexion est au dessus de HTTP, mercurial
589 recompresse le flux entier de données en utilisant un algorithme de
590 compression qui donne un meilleur taux de compression (l'algorithme
591 Burrows-Wheeler utilisé principalement par le package de
592 compression <literal>bzip2</literal>). Cette combinaison de
593 l'algorithme et de compression du flux entier (plutôt que pour une
594 révision à la fois) réduit substanciellement le nombre de bits qui
595 sont transférés, résultant dans une performance réseau accrue sur
596 la plupart des supports.</para>
598 <para id="x_329">Si la connexion est au dessus de
599 <command>ssh</command>, Mercurial <emphasis>ne</emphasis>
600 recompresse <emphasis>pas</emphasis> le flux puisque
601 <command>ssh</command> peut déjà le faire par lui même. Vous pouvez
602 demander à Mercurial de toujours utiliser la compression
603 <command>ssh</command> en éditant le fichier
604 <filename>.hgrc</filename> de votre répertoire personnale comme ci
605 dessous.</para>
607 <programlisting>[ui]
608 ssh = ssh -C</programlisting>
610 </sect3>
611 </sect2>
612 <sect2>
613 <title>Ordres de Lecture/Écriture et atomicité</title>
615 <para id="x_32a">Ajouter à la fin des fichiers n'est pas toute
616 l'histoire lorsque l'on cherche à garantir que le lecteur ne verra
617 pas qu'une écriture partielle. Si vous relisez <xref
618 linkend="fig:concepts:metadata"/>, les révisions dans le changelog
619 pointent vers les révisions dans le manifest, et les révisions du
620 manifest pointent vers les révisions du filelog. Cette hiérarchie est
621 délibérée.</para>
623 <para id="x_32b">L'écriture commence une transaction en écrivant dans
624 le filelog et dans les données du manifest, et n'écrit aucune donnée
625 changelog tant que ce n'est pas terminé. La lecture commence en
626 lisant les données du changelog, puis les données du manifest, et
627 enfin les données du filelog.</para>
629 <para id="x_32c">Puisque que l'écriture ne finit pas d'écrire les
630 données du filelog et du manifest avant d'écrire dans le changelog,
631 la lecture ne verra jamais un pointeur vers une révision du manifest
632 partiellement écrite à partir du changelog, et ne lira jamais un
633 pointeur vers une révision du filelog partiellement écrite dans le
634 manifest.</para>
636 </sect2>
637 <sect2>
638 <title>Accès concurrent</title>
640 <para id="x_32d">La garantie de l'ordre de lecture/écriture et
641 de l'atomicite signifie que Mercurial n'a jamais besoin de poser de
642 <emphasis>lock</emphasis> sur un dépôt lorsqu'il lit des données,
643 même si le dépôt est en train d'être écrit au même moment que la
644 lecture a lieue. Ceci a un grand impact sur la fiabilité ; vous
645 pouvez avoir un nombre arbitraire de processus Mercurial qui lisent
646 dans risque en même temps les données d'un dépôt, peu importe s'il
647 est en train d'être lu ou non.</para>
649 <para id="x_32e">La nature sans <quote>lock</quote> de la lecture
650 signifie que si vous partagez un dépôt sur un système
651 multi-utilisateurs, vous n'avez pas besoin de donner aux autres
652 utilisateurs locaux la permission d'<emphasis>écrire</emphasis> sur
653 votre dépôt pour qu'ils soient capable de faire un clone ou un pull
654 des changements à partir de celui ci ; ils ont seulement besoin de la
655 permission en <emphasis>lecture</emphasis>. (Il
656 <emphasis>ne</emphasis> s'agit <emphasis>pas</emphasis> d'une
657 fonctionnalité commune à travers les systèmes de gestion de révision,
658 donc ne prenez pas ça pour garanti ! La plupart ont besoin que les
659 lecteurs soient capables de mettre un lock sur le dépôt pour y
660 accéder en toute sécurité, et ceci demande des permissions en
661 écriture, sur au moins un dépertoire, ce qui provoque biensûr toutes
662 sortes de problèmes néfastes et ennuyants relatifs à la sécurité et à
663 l'administration.)</para>
665 <para id="x_32f">Mercurial utilise des locs pour assurer qu'un seul
666 processus peut écrire dans le dépôt à un moment donné (le mécanisme
667 de lock est sûr, même sur des systèmes de fichiers qui sont connus
668 pour être hostiles aux locks, comme NFS). Si un dépôt dispose d'un
669 lock, un processus qui cherche à écrire va attendre un peu avant de
670 retenter pour voir si le dépôt perd son lock, mais le dépôt garde
671 trop longtemps son lock, le processus qui tente d'écrire va expirer
672 (time out) après un moment. Celà veut dire par exemple que vous
673 scripts lancés quotidiennement n'attendront pas toujours et boucler
674 si un système crashait sans avertissement, par exemple. (Oui, le
675 timeout est configurable, de zéro à l'infini.)</para>
677 <sect3>
678 <title>Accès dirstate sûr</title>
680 <para id="x_330">Comme avec les données de révision, Mercurial ne prend pas
681 de lock pour lire le fichier dirstate ; il n'acquier pas un lock pour
682 y écrire. Pour empécher la possibilité de lire une copie partiellement
683 écrite du fichier dirstate, Mercurial écrit à un fichier avec un nom
684 unique dans le même répertoire que le fichier dirstate, ensuite renomme
685 le fichier temporaire automatiquement en <filename>dirstate</filename>.
686 Le fichier nommé <filename>dirstate</filename> est ainsi garanti d'être
687 écrit totalement, et non partiellement.</para>
689 </sect3>
690 </sect2>
691 <sect2>
692 <title>Empécher les recherches</title>
694 <para id="x_331">L'absence de recherche sur les têtes de disques est
695 critique pour la performance de Mercurial, puisque toute recherche
696 est beaucoup plus coûteuse comparativement à une grosse opération de
697 lecture.</para>
699 <para id="x_332">C'est pour ça, par exemple, que le dirstate est stocké
700 dans un unique fichier. S'il y avait eu un dirstate par répertoire
701 que Mercurial suivait, le disque aurait recherché une fois par
702 répertoire. Au lieu de ça, Mercurial lit entièrement un unique
703 fichier, en une étape.</para>
705 <para id="x_333">Mercurial utilise aussi un schéma <quote>copie à
706 l'écriture</quote> lorsqu'il clone un dépôt sur un stockage local.
707 Au lieu de copier chaque fichier revlog depuis l'ancien dépôt vers le
708 nouveau dépôt, il crée un <quote>lien physique</quote>, qui est le
709 plus court chemin pour dire <quote>Ces deux noms pointent vers le
710 même fichier</quote>. Lorsque Mercurial est sur le point d'écrire
711 sur l'un des revlogs de ces fichiers, il vérifie si le nombre de noms
712 pointant sur ce fichier est plus grand que un. Si c'est le cas, plus
713 d'un dépôt utilise le fichier, donc Mercurial crée une nouvelle copie
714 du fichier qui est privée à ce dépôt.</para>
716 <para id="x_334">Quelques développeurs de systèmes de gestion de
717 révision ont montré que cette idée de faire une copie privée complète
718 d'un fichier n'est pas vraiment efficace dans son utilisation du
719 stockage. Bien que ce soit vrai, le stockage est peu onéreux, et
720 cette méthode donne la plus grande performance lorsque l'on reporte
721 la plupart des journalisations au système d'exploitation. Un schéma
722 alternatif réduirait certainement la performance tout en augmentant
723 la complexité du logiciel, mais la vitesse et la simplicité sont els
724 clefs du <quote>sentiment</quote> de l'utilisation
725 quotidienne.</para>
727 </sect2>
728 <sect2>
729 <title>Autres contenus du dirstate</title>
731 <para id="x_335">Puisque Mercurial ne vous force pas à dire lorsque
732 vous modifiez un fichier, il utilise le dirstate pour stocker
733 certaines informations supplémentaires pour déterminer efficacement
734 si vous avez ou non modifié un fichier. Pour chaque fichier du
735 répertoire de travail, il stocke l'heure à laquelle il a été modifié,
736 ainsi que la taille du fichier à cette heure.</para>
738 <para id="x_336">Lorsque vous faites explicitement un <command
739 role="hg-cmd">hg add</command>, <command role="hg-cmd">hg
740 remove</command>, <command role="hg-cmd">hg rename</command> ou
741 <command role="hg-cmd">hg copy</command> sur des fichiers, Mercurial
742 met à jour le dirstate afin de savoir quoi faire lorsque vous
743 effectuez un commit.</para>
745 <para id="x_337">Le dirstate aide Mercurial à vérifier efficacement le
746 status des fichiers dans un dépôt.</para>
748 <itemizedlist>
749 <listitem> <para id="x_726"> Lorsque Mercurial vérifie l'état d'un
750 fichier du répertoire de travail, il compare d'abord la date de
751 dernière modification du fichier avec celle enregistrée dans le
752 dirstate qui correspond à Mercurial a écrit en dernier sur ce
753 fichier. Si le temps de dernière modification correspond au temps
754 où Mercurial a écrit le fichier, celui ci n'a pas été modifié,
755 donc mercurial n'a pas besoin de revérifier.</para> </listitem>
756 <listitem> <para id="x_727"> Si la taille du fichier a changé, celui
757 ci a été modifié. Si la date de modification a changé mais que la
758 taille est restée inchangée, seulement à ce moment là Mercurial
759 doit vérifier le contenu du fichier pour savoir s'il a été
760 modifié.</para> </listitem>
761 </itemizedlist>
763 <para id="x_728">Enregistrer la date de modification et la taille
764 réduit grandement le nombre d'opérations de lecture que Mercurial
765 doit effectuer lorsque l'on utilise une commande comme <command>hg
766 status</command>. Le résultat est un grand gain de
767 performance.</para>
768 </sect2>
769 </sect1>
770 </chapter>
772 <!--
773 local variables:
774 sgml-parent-document: ("00book.xml" "book" "chapter")
775 end:
776 -->