Quand deux fichiers ont « le même contenu » mais que diff affiche une foule de différences, les espaces en sont souvent la cause : l'éditeur a supprimé les espaces en fin de ligne, converti les tabulations en espaces ou changé la largeur de l'indentation. Les outils diff proposent des options pour ignorer ces différences, mais chaque option n'ignore pas la même chose : il faut savoir précisément ce qu'elle fait.
Les options d'espaces de GNU diff
| Option | Nom long | Ce qui est ignoré |
|---|---|---|
-Z | --ignore-trailing-space | Les espaces en fin de ligne |
-E | --ignore-tab-expansion | Les différences dues à l'expansion des tabulations en espaces |
-b | --ignore-space-change | Les variations de quantité d'espaces, les espaces en fin de ligne |
-w | --ignore-all-space | Tous les espaces |
-B | --ignore-blank-lines | Les modifications qui n'ajoutent ou ne suppriment que des lignes vides |
-i | --ignore-case | La casse |
--strip-trailing-cr | Le caractère CR en fin de ligne d'entrée |
Les options correspondantes de git diff
Voici ce qu'en dit la documentation de git :
--ignore-cr-at-eol: ignore le retour chariot (CR) en fin de ligne lors de la comparaison.--ignore-space-at-eol: ignore les changements d'espaces en fin de ligne.-b,--ignore-space-change: ignore les changements de quantité d'espaces. Les espaces en fin de ligne sont ignorés, et toute suite d'un ou plusieurs espaces est considérée comme équivalente.-w,--ignore-all-space: ignore les espaces lors de la comparaison des lignes, y compris quand une ligne en contient et que l'autre n'en a pas.--ignore-blank-lines: ignore les modifications dont toutes les lignes sont vides.
La différence décisive entre -b et -w
On confond souvent ces deux options. Tout tient à une question : distingue-t-on la présence ou l'absence d'espace ?
| Gauche | Droite | -b (quantité d'espaces ignorée) | -w (tous les espaces ignorés) |
|---|---|---|---|
a b | a b | Identique | Identique |
a b | ab | Différent | Identique |
x = 1 | x=1 | Différent | Identique |
if (a) + espaces en fin de ligne | if (a) | Identique | Identique |
| Indentation d'une tabulation | Indentation de 4 espaces | Identique | Identique |
-b réduit chaque groupe d'espaces à un seul espace, tandis que -w supprime tous les espaces. C'est pourquoi -w considère comme identiques x = 1 et x=1, et même int a et inta.
Le danger quand l'indentation a un sens
Dans les fichiers où l'indentation fait partie de la syntaxe, comme Python, YAML ou les Makefile, les options d'espaces peuvent masquer une vraie modification.
if ready:
start()
notify()
if ready:
start()
notify()
Dans la seconde version, notify() est sorti du bloc if et le comportement a changé, mais avec -w tous les espaces sont supprimés et la différence disparaît. -b, lui, la détecte, car l'espace en début de ligne passe de « présent » à « absent ». En revanche, si l'indentation passe de 4 à 8 espaces et que le code entre dans un bloc plus profond, seule la quantité d'espaces a changé : -b ne voit rien non plus.
La méthode sûre consiste à comparer sans option d'espaces les fichiers où l'indentation compte. Prenez l'habitude d'utiliser les options d'espaces pour « vérifier qu'une modification n'est qu'un nettoyage », et de faire la vérification finale sans option.
La portée de l'option lignes vides (-B)
-B et --ignore-blank-lines de git masquent les modifications composées uniquement de lignes vides. Si l'ajout d'une ligne vide se trouve dans le même hunk qu'une vraie modification, cette ligne vide peut rester affichée. L'option est utile pour un document où l'on a changé le nombre de lignes vides entre paragraphes, ou quand un formateur de code a ajusté les lignes vides entre fonctions.
Correspondance avec les options de ce site
| Ce site | GNU diff le plus proche | git diff le plus proche |
|---|---|---|
| Espaces : comparer tels quels | (aucune option) | (aucune option) |
| Espaces : ignorer les espaces en fin de ligne | -Z | --ignore-space-at-eol |
| Espaces : ignorer la quantité d'espaces | -b | -b |
| Espaces : ignorer tous les espaces | -w | -w |
| Ignorer la casse | -i | (pas d'équivalent) |
| Ignorer les lignes vides | proche de -B (lignes vides exclues de la comparaison) | proche de --ignore-blank-lines |
| Normaliser les fins de ligne | --strip-trailing-cr + dernier saut de ligne ignoré | proche de --ignore-cr-at-eol |
L'option « Ignorer les lignes vides » de ce site retire complètement les lignes vides de la comparaison et se contente de les afficher en couleur atténuée. De plus, les options d'ignorance s'appliquent aussi au surlignage dans la ligne : avec « ignorer la quantité d'espaces », les passages qui ne diffèrent que par le nombre d'espaces ne sont pas surlignés.
Essayer avec cet outil
Collez les exemples du tableau ci-dessus dans le comparateur de texte et changez les options d'espaces une à une : la différence saute aux yeux. Les « différences invisibles » comme le CR en fin de ligne ou le saut de ligne en fin de fichier sont traitées dans Caractères de fin de ligne et différences invisibles, et la lecture du résultat sous forme de patch dans Lire un diff unifié.