L'interface entre Subversion et les outils de comparaison
(de deux ou trois fichiers) remonte à l'époque où Subversion,
pour afficher les différences de manière contextuelle,
utilisait directement la suite d'outils GNU de comparaison,
plus précisément les utilitaires diff et
diff3. Pour obtenir le comportement désiré
par Subversion, l'appel à ces programmes se faisait avec une
ribambelle d'options et de paramètres dont la plupart étaient
spécifiques à ces utilitaires. Plus tard, Subversion s'est doté
de sa propre bibliothèque de comparaison et, afin de conserver
la possibilité de choisir, les options
--diff-cmd
et --diff3-cmd
ont été ajoutées au client en ligne de commande pour que les
utilisateurs allergiques à la nouvelle bibliothèque puissent
indiquer facilement leur souhait de se servir des utilitaires
GNU diff et diff3. Si ces options étaient utilisées,
Subversion ignorait purement et simplement
sa bibliothèque interne de comparaison et appelait
alors ces programmes externes, avec leurs listes d'arguments
longue comme un jour sans pain et leurs autres spécificités.
Les choses sont restées en l'état.
Il n'a pas fallu longtemps pour que les adeptes de Subversion comprennent que si l'on pouvait utiliser les utilitaires GNU diff et diff3 situés à un endroit précis du disque, on pouvait alors aussi utiliser ce mécanisme pour utiliser d'autres outils de comparaison. Après tout, Subversion ne vérifiait pas que les programmes qu'il lançait faisaient bien partie de la suite des outils GNU de comparaison. Mais la seule chose que l'on peut configurer dans l'utilisation de programmes externes est leur emplacement sur le disque ; pas les options, ni l'ordre des paramètres, ni le reste. Subversion continue à envoyer toutes les options des utilitaires GNU à votre programme de comparaison, indépendamment du fait que votre programme en tienne compte ou non. Et c'est là que la plupart des utilisateurs ne comprennent pas la logique de la chose.
La clé pour utiliser des outils externes de comparaison de deux ou trois fichiers (autres que les programmes GNU diff et diff3 bien sûr) avec Subversion est de créer des scripts d'interface qui convertissent les données fournies par Subversion en données compréhensibles par l'outil de comparaison que vous utilisez, puis de convertir les sorties de votre outil vers le format attendu par Subversion : le format que les outils GNU auraient utilisé. Les sections suivantes détaillent les spécificités de ce qu'attend Subversion.
Note | |
---|---|
La décision de lancer une comparaison entre deux ou trois
fichiers dans le cadre d'une opération Subversion est
entièrement du ressort de Subversion et est conditionnée,
en autres, au fait que les fichiers soient lisibles par un
humain comme indiqué par leur propriété
|
Subversion 1.5 introduit la résolution interactive des
conflits (décrite dans la section intitulée « Résoudre les conflits (fusionner des modifications) »)
et l'une des options proposées à l'utilisateur est de lancer
un outil de fusion externe. Si cette action est choisie,
Subversion consultera l'option merge-tool-cmd
de la zone de configuration des exécutables, susceptible de
contenir le nom d'un outil externe de fusion et, s'il en
trouve un, lancera cet outil avec les fichiers appropriés en
paramètres. Il y a deux différences notables avec l'outil de
comparaison de trois fichiers. D'abord, l'outil de comparaison
est toujours utilisé pour afficher les différences entre trois
fichiers alors que l'outil de fusion est employé uniquement
quand l'application de comparaison a détecté un conflit.
Ensuite, l'interface est beaucoup plus propre — votre outil de
fusion a seulement besoin d'accepter comme paramètres en ligne
de commande les chemins des quatre fichiers suivants : le
fichier de référence, le « leur » (qui contient
les modifications en provenance du dépôt), le
« mien » (qui contient les modifications locales)
et le fichier dans lequel sera placé le contenu final à
stocker.
Subversion appelle les programmes externes de comparaison avec des paramètres compatibles avec la suite d'outils de comparaison GNU et s'attend à ce que le programme renvoie un code d'erreur signifiant la réussite de la comparaison. Pour la plupart des programmes de comparaison alternatifs, seuls les sixième et septième arguments, indiquant les chemins vers les fichiers à comparer, respectivement placés à gauche et à droite, sont intéressants. Notez que Subversion lance le programme de comparaison pour chaque fichier concerné par l'opération Subversion, ce qui peut vous amener à avoir plusieurs instances simultanément si votre programme fonctionne de manière asynchrone (ou s'il est placé en arrière-plan). Enfin, Subversion s'attend à ce que votre programme retourne un code d'erreur de 1 s'il a détecté des différences ou 0 sinon. Tout autre code d'erreur est considéré comme une erreur fatale [53].
L'Exemple 7.2, « interface-diff.py » et l' Exemple 7.3, « interface-diff.bat » sont des modèles de scripts d'interface pour un outil externe de comparaison, respectivement en langage Python et en langage de script Windows :
Exemple 7.2. interface-diff.py
#!/usr/bin/env python import sys import os # Indiquez ici le chemin de votre outil de comparaison favori. DIFF = "/usr/local/bin/mon-diff-perso" # Subversion fournit les chemins voulus dans les deux derniers arguments. GAUCHE = sys.argv[-2] DROITE = sys.argv[-1] # Appelons la commande de comparaison (modifiez la ligne suivante # en accord avec votre programme de comparaison). cmd = [DIFF, '--left', GAUCHE, '--right', DROITE] os.execv(cmd[0], cmd) # Le code d'erreur renvoyé doit être : # 0 si aucune différence n'est détectée, # 1 s'il y a des différences. # Tout autre code est traité comme une erreur fatale.
Exemple 7.3. interface-diff.bat
@ECHO OFF REM Indiquez ici le chemin de votre outil de comparaison favori. SET DIFF="C:\Program Files\Super Progs\Mon Diff Perso.exe" REM Subversion fournit les chemins voulus dans les deux derniers arguments. REM Ce sont les paramètres 6 et 7 (sauf si vous utilisez svn diff -x, REM auquel cas tout est possible). SET GAUCHE=%6 SET DROITE=%7 REM Appelons la commande de comparaison (modifiez la ligne suivante REM en accord avec votre programme de comparaison). %DIFF% --left %GAUCHE% --right %DROITE% REM Le code d'erreur renvoyé doit être : REM 0 si aucune différence n'est détectée, REM 1 s'il y a des différences. REM Tout autre code est traité comme une erreur fatale.
Subversion appelle les programmes externes de fusion avec des paramètres compatibles avec l'outil GNU diff3 et s'attend à ce que le programme externe retourne un code d'erreur correct et que le fichier résultant de l'opération de fusion soit envoyé vers la sortie standard (de façon à ce que Subversion puisse le rediriger vers le fichier suivi en versions approprié). Pour la plupart des programmes de fusion alternatifs, seuls les neuvième, dixième et onzième arguments (les chemins des fichiers qui contiennent les versions « mien », « original » et « leur » respectivement) sont intéressants. Notez que puisque Subversion utilise la sortie de votre programme de fusion, votre script d'interface ne doit pas se terminer avant que la sortie n'ait été fournie à Subversion. Quand il se termine, il doit retourner un code d'erreur de 0 si la fusion s'est correctement déroulée ou de 1 si des conflits non résolus persistent dans la sortie. Tout autre code d'erreur est considéré comme une erreur fatale.
L'Exemple 7.4, « interface-diff3.py » et l'Exemple 7.5, « interface-diff3.bat » sont des modèles pour des scripts d'interface vers un programme externe de fusion en langage Python et script Windows respectivement.
Exemple 7.4. interface-diff3.py
#!/usr/bin/env python import sys import os # Indiquez ici le chemin de votre outil de fusion favori. DIFF3 = "/usr/local/bin/mon-outil-de-fusion" # Subversion fournit les chemins voulus dans les trois derniers arguments. MIEN = sys.argv[-3] VIEUX = sys.argv[-2] LEUR = sys.argv[-1] # Appelons la commande de fusion (modifiez la ligne suivante # en accord avec votre outil de fusion). cmd = [DIFF3, '--older', VIEUX, '--mine', MIEN, '--yours', LEUR] os.execv(cmd[0], cmd) # Après avoir effectué la fusion, le script doit envoyer le # contenu du fichier résultant vers la sortie standard (stdout) # Faites le à votre convenance. # Le code d'erreur renvoyé doit être : # 0 si la fusion a bien fonctionné, # 1 s'il reste des conflits non résolus. # Tout autre code est traité comme une erreur fatale.
Exemple 7.5. interface-diff3.bat
@ECHO OFF REM Indiquez ici le chemin de votre outil de fusion favori. SET DIFF3="C:\Program Files\Super Progs\Mon Outil De Fusion.exe" REM Subversion fournit les chemins voulus dans les trois derniers arguments. REM Ce sont les paramètres 9, 10 et 11. Mais nous n'avons accès qu'à REM neuf paramètres en même temps, nous effectuons donc deux décalages REM pour obtenir les paramètres manquants. SHIFT SHIFT SET MIEN=%7 SET VIEUX=%8 SET LEUR=%9 REM Appelons la commande de fusion (modifiez la ligne suivante REM en accord avec votre outil de fusion). %DIFF3% --older %VIEUX% --mine %MIEN% --yours %LEUR% REM Après avoir effectué la fusion, le script doit envoyer le REM contenu du fichier résultant vers la sortie standard (stdout) REM Faites le à votre convenance. REM Le code d'erreur renvoyé doit être : REM 0 si la fusion a bien fonctionné, REM 1 s'il reste des conflits non résolus. REM Tout autre code est traité comme une erreur fatale.
[53] Le manuel du diff GNU indique : « Un code de retour valant 0 signifie qu'aucune différence n'a été trouvée, 1 signifie que des différences sont apparues, 2 indique une erreur ».