Ce chapitre détaille les objectifs poursuivis par le projet xdiff, ses principaux choix techniques et l'architecture logicielle qui en a résulté.
Le versionnement est un domaine déjà ancien, disposant d'outils génériques et efficaces. On peut dès lors se demander l'intérêt de créer un n-ième outil de versionnement, limité qui plus est à une petite classe de fichiers et codé dans un langage, Java, tristement célèbre pour ses lenteurs réelles ou supposées.
La réponse tient en un seul mot, XML.
XML est né vers 1996 de la volonté d'offrir une alternative à HTML permettant une stricte séparation du contenu de la présentation[1]. Comme HTML, il s'agit d'un sous-ensemble simplifié de SGML ; mais contrairement à HTML cette simplification ne s'est pas faite au détriment d'une rigueur syntaxique permettant le traitement automatisé des documents, bien au contraire. XML impose l'application de règles strictes là où SGML faisait preuve d'un certain laxisme.
Depuis XML s'est largement répandu, dépassant son cadre initial pour s'imposer comme format universel de documents structurés, qu'il s'agisse d'un fichier de configuration, d'un échange de données, la description d'une interface où même une forme de base de données.
À noter que dans tous ces derniers cas XML s'est substitué à des formats spécialisés ayant la plupart du temps un ratio contenu/taille beaucoup plus favorable[2]. Pourquoi ? La plupart du temps la généricité du format, le grand nombre d'outils disponibles, le fait qu'il soit directement lisible par un être humain ont été préférés à l' " efficacité " de l'existant.
XML a en effet hérité de SGML une syntaxe permettant la validation de fichiers par des outils spécialisés. Ceci, joint au fait qu'elle est facilement compréhensible par un être humain en font un langage robuste sur lequel il est aisé d'intervenir en cas de problème. Ajoutez à cela le coût toujours décroissant de l'unité de stockage électronique, de la bande passante, etc, et le choix était vite fait. La loi de Murphy est malheureusement plus coriace.
Mais lorsque l'on désire comparer deux documents XML, on retombe dans les travers antérieurs.
Des outils comme diff permettent de générer rapidement des différences entre deux versions d'un même fichier texte[3], les appliquer pour passer d'une version à une autre. Ils ont été validés par des années d'usage, sont génériques et considérés comme très efficaces.
Néanmoins, un corollaire de cette généricité est leur ignorance totale de la structure des documents traités. L'ajout d'une espace ou une tabulation seront traités avec autant de rigueur qu'un changement autrement plus important du point de vue de la signification d'un document. Des changements n'ayant aucun rapport seront agrégés ; à l'inverse, des lignes implicitement modifiées par l'insertion où la suppression de lignes antérieures seront totalement ignorées.
Tout ceci rend les différences calculées par diff totalement inexploitables pour autre chose que le passage d'une version à une autre. Un logiciel destiné à traiter les évolutions d'un document structuré[4] où même un être humain cherchant simplement à comprendre les changements opérés entre deux versions de ce même document devront appliquer la différence et aller chercher dans le document complet le contexte nécessaire à son interprétation.
Une différence classique ne sert alors plus que comme moyen commode d'obtenir un index des changements survenus.
Or c'est précisément ce type d'opérations qu'XML est conçu pour éviter.
Un document XML est fortement structuré. Les relations entre éléments sont claires ; ce qui a un sens et ce qui n'est qu'un artefact de présentation aussi. La génération automatique de différences mettant en évidence le sens réel des changements est donc possible.
Par exemple, le fait qu'un élément englobant[5] soit supprimé ou change de type n'est pas sans conséquence sur la signification de ses fils. Ceux-ci seront pourtant ignorés par un diff classique.
À l'inverse, la modification d'une indentation à l'extérieur d'un élément ou l'ordre de ses attributs sont purement cosmétiques. Si on peut choisir de l'enregistrer dans un souci de cohérence, ce n'est nullement une obligation.
Un générateur de différences structurées devra donc remplir les obligations suivantes :
prendre en compte les modifications implicites : gérer les noeuds et leurs descendants de manière atomique, agréger les modifications qui ont un rapport ;
générer des différences aisément exploitables par un autre programme ou un être humain. Vu la souplesse du langage XML, il est aussi possible de l'employer ici.
Par contre, seront considérées comme optionnelles[6] la conservation des propriétés suivantes d'un fichier :
Enfin, il peut être désirable de réfléchir à l'insertion d'un tel générateur dans un gestionnaire de versions plus vaste.
| [1] | XML étant le langage dédié au contenu. |
| [2] | Et faisant d'ailleurs généralement appel à des champs binaires. |
| [3] | Voir Annexe A, Exemple A-2. |
| [4] | Par exemple agissant en fonction de la valeur d'un attribut d'un élément XML. |
| [5] | Dit encore racine ou parent. |
| [6] | Mais souhaitables si l'on désire rester compatible avec des outils de versionnement classiques |