Comment coloriser diff sur la ligne de commande?

504

Quand j'ai un diff, comment puis-je le coloriser pour qu'il soit beau? Je le veux pour la ligne de commande, donc s'il vous plaît pas de solutions GUI.

daniel kullmann
la source
6
Un système d'exploitation / shell particulier?
Rowland Shaw
4
Essayez github.com/walles/riff . En prime, il met en évidence les parties des lignes qui ont changé.
Johan Walles

Réponses:

608

Les pages de diffmanuel ne proposent aucune solution pour la colorisation de l'intérieur. Veuillez envisager d'utiliser colordiff. C'est un wrapper diffqui produit la même sortie que diff, sauf qu'il augmente la sortie en utilisant la coloration syntaxique pour augmenter la lisibilité:

diff old new | colordiff

ou juste:

colordiff old new

Installation:

  • Ubuntu / Debian: sudo apt-get install colordiff
  • OS X: brew install colordiffouport install colordiff
kaji
la source
45
Je viens de le découvrir moi-même :-). Il peut être canalisé en moins en utilisant less -R, qui affiche correctement les séquences d'échappement des couleurs.
daniel kullmann
34
Peut simplement utiliser la syntaxe: colordiff file1 file2
Felipe Alvarez
3
Hélas, cela ne fonctionne pas pour la sortie côte à côte ( -yoption à activer) ☹ La vimdiffsuggestion ci-dessous est probablement une meilleure façon
Hi-Angel
8
colordifffonctionne bien pour svn diff | colordiff(c'est-à-dire dans les situations où vous n'avez que le diff, pas les deux fichiers étant diffed).
Cornstalks
8
En tant que mise à jour du commentaire de @ Hi-Angel: colordiff a été mis à jour et inclut désormais le -ysupport côte à côte ( ).
Bailey Parker
333

Utilisez Vim :

diff /path/to/a /path/to/b | vim -R -

Ou mieux encore, VimDiff (ou vim -d, qui est plus court à taper) affichera les différences entre deux, trois ou quatre fichiers côte à côte.

Exemples:

vim -d /path/to/[ab]

vimdiff file1 file2 file3 file4
Johnsyweb
la source
7
@Jichao: Je préfère apprendre les commandes plutôt que de les alias. De cette façon, je peux les utiliser n'importe où, même lorsque mes fichiers dot ne sont pas disponibles.
Johnsyweb
1
@AquariusPower: ctrl-cet ctrl-xavoir d'autres utilisations dans Vim. ctrl-qest capturé par de nombreux terminaux. Voir Écrire et quitter pour trouver la manière qui convient le mieux à vos besoins.
Johnsyweb
1
Tout d'abord, quel genre de coque est-ce? zsh? Je ne reconnais pas la =(...)construction. Deuxièmement, j'avais diff -ur a bà l'esprit.
x-yuri
1
Cette solution est meilleure que la réponse acceptée, car elle ne nécessite pas de droits d'administrateur système et d'installer un outil supplémentaire
amanzoor
173

En fait, il semble y avoir encore une autre option (que je n'ai remarquée que récemment, lors de l'exécution du problème décrit ci-dessus):

git diff --no-index <file1> <file2>
# output to console instead of opening a pager
git --no-pager diff --no-index <file1> <file2>

Si vous disposez de Git (que vous utilisez peut-être déjà de toute façon), vous pourrez l'utiliser à des fins de comparaison, même si les fichiers eux-mêmes ne sont pas sous contrôle de version. S'il n'est pas activé pour vous par défaut, l'activation de la prise en charge des couleurs ici semble être beaucoup plus facile que certaines des solutions de contournement mentionnées précédemment.

Lars Baehren
la source
19
C'est bien, mais malheureusement cela ne fonctionne pas lorsque les entrées sont des tuyaux. Par exemple, la comparaison de fichiers binaires via git diff <(xxd file1) <(xxd filed)ne fonctionne pas.
Michael Anderson
8
Curieusement, au moins l'un des fichiers doit être «en dehors du référentiel actuel», selon git help diff. Donc, si votre diff git est vide, essayez de cdsortir d'où vous êtes.
Mauvaise demande
7
Pour activer les couleurs pour git diff:git config color.diff auto
JWhy
2
super simple et rapide
EE33
31
Si les deux fichiers se trouvent dans le référentiel actuel, utilisez git diff --no-indexpour comparer deux fichiers.
Olivier 'Ölbaum' Scherler
95

diff --color option a été ajoutée à GNU diffutils 3.4 (2016-08-08)

Il s'agit de l' diffimplémentation par défaut de la plupart des distributions, qui sera bientôt disponible.

Ubuntu 18.04 a diffutils3.6 et l'a donc.

Sur 3.5, cela ressemble à ceci:

entrez la description de l'image ici

Testé:

diff --color -u \
  <(seq 6 | sed 's/$/ a/') \
  <(seq 8 | grep -Ev '^(2|3)$' | sed 's/$/ a/')

Apparemment ajouté dans la validation c0fa19fe92da71404f809aafb5f51cfd99b1bee2 (mars 2015).

Différence au niveau du mot

Comme diff-highlight. Pas possible, semble-t-il, demande de fonctionnalité: https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg00001.html

Sujets associés:

ydiff le fait cependant, voir ci-dessous.

ydiff différence de niveau de mot côte à côte

https://github.com/ymattw/ydiff

Est-ce le Nirvana?

python3 -m pip install --user ydiff
diff -u a b | ydiff -s

Résultat:

entrez la description de l'image ici

Si les lignes sont trop étroites (80 colonnes par défaut), ajustez à l'écran avec:

diff -u a b | ydiff -w 0 -s

Contenu des fichiers de test:

une

1
2
3
4
5 the original line the original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the original line
16
17
18
19
20

b

1
2
3
4
5 the original line teh original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the origlnal line
16
17
18
19
20

ydiff Intégration Git

ydiff s'intègre à Git sans aucune configuration requise.

De l'intérieur d'un référentiel git, au lieu de git diff, vous pouvez faire simplement:

ydiff -s

et au lieu de git log:

ydiff -ls

Voir aussi: Comment puis-je obtenir un diff côte à côte lorsque je fais "git diff"?

Testé sur Ubuntu 16.04, git 2.18.0, ydiff 1.1.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
Voici la documentation.
Alexey
1
Dans ce fil de liste de diffusion: There is no word-highlighting, yet- des mises à jour? C'est pour cela que je suis venu à cette question (je veux une grep --colorsortie de type diff).
i336_
@ i336_ aucune mise à jour malheureusement, si j'en reçois, je mettrai à jour la question. Ping moi si tu trouves quelque chose.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Soit dit en passant git diff --colorfonctionne aussi. Utile lorsque vous travaillez sur ssh.
Nagev
Diff trop grand? usediff --color=always | less -R
inetphantom
69

Et pour les occasions où un yum install colordiffou un apt-get install colordiffn'est pas une option en raison d'une contrainte insensée hors de votre contrôle immédiat, ou si vous vous sentez juste fou , vous pouvez réinventer la roue avec une ligne de sed:

sed 's/^-/\x1b[41m-/;s/^+/\x1b[42m+/;s/^@/\x1b[34m@/;s/$/\x1b[0m/'

Jetez cela dans un script shell et canalisez une sortie diff unifiée à travers lui.

Il rend les marqueurs de morceau bleus et met en évidence les nouveaux / anciens noms de fichiers et les lignes ajoutées / supprimées en arrière-plan vert et rouge, respectivement. 1 Et cela rendra les changements d' espace de fuite 2 plus visibles que ne peut le faire Colordiff.


1 Soit dit en passant, la raison pour laquelle les noms de fichiers sont mis en évidence de la même manière que les lignes modifiées est que pour différencier correctement les noms de fichiers et les lignes modifiées, il faut analyser correctement le format diff, ce qui n'est pas quelque chose à résoudre avec une expression régulière. Les mettre en évidence les mêmes fonctionne "assez bien" visuellement et rend le problème trivial. Cela dit, il y a quelques subtilités intéressantes .

2 Mais pas les onglets de fin. Apparemment, les onglets ne reçoivent pas leur arrière-plan, du moins dans mon xterm. Cela fait ressortir un peu les changements de tabulation vs d'espace.

retracile
la source
5
@Matt: Voici une approche par force brute pour un Mac: sed "s/^-/`echo -e \"\x1b\"`[41m-/;s/^+/`echo -e \"\x1b\"`[42m+/;s/^@/`echo -e \"\x1b\"`[34m@/;s/$/`echo -e \"\x1b\"`[0m/"(même si je m'attends à ce qu'il y ait une meilleure façon).
retracile
1
Hmm, ça a fonctionné ... a donné aux 3 tirets entre chaque morceau un fond rose.
Matt Montag
Manuelle illisible, non maintenable sans option pour changer facilement les couleurs par exemple.
1
Mec c'est génial! Marche à suivre! C'est une belle magie de sed.
fthinker
6
sed 's / ^ - / \ x1b [31m - /; s / ^ + / \ x1b [32m + /; s / ^ @ / \ x1b [34m @ /; s / $ / \ x1b [0m /' a aussi fière allure
Yura
16

Vous pouvez changer la configuration de subversion pour utiliser colordiff

~ / .subversion / config.diff

 ### Set diff-cmd to the absolute path of your 'diff' program.
 ###   This will override the compile-time default, which is to use
 ###   Subversion's internal diff implementation.
-# diff-cmd = diff_program (diff, gdiff, etc.)
+diff-cmd = colordiff

via: https://gist.github.com/westonruter/846524

Azd325
la source
svn: Can't start process 'colordiff': Ressource temporairement indisponible
niken
Avez-vous installé colordiff?
Azd325
Oui, j'ai également essayé de coder en dur le chemin (en cours d'exécution dans cygwin)
niken
idk try might this superuser.com/questions/635995/…
Azd325
12

Couleur, mot-niveau diff ouput

Voici ce que vous pouvez faire avec le script ci-dessous et diff-highlight :

Capture d'écran diff couleur

#!/bin/sh -eu

# Use diff-highlight to show word-level differences

diff -U3 --minimal "$@" |
  sed 's/^-/\x1b[1;31m-/;s/^+/\x1b[1;32m+/;s/^@/\x1b[1;34m@/;s/$/\x1b[0m/' |
  diff-highlight

(Crédit à la réponse de @ retracile pour la sedmise en évidence)

Tom Hale
la source
Comment utiliser cette sortie dans GVim?
Hemant Sharma
Pour vim, utilisez un plugin, par exemple diffchar .
Tom Hale
10

J'utilise grc(Generic Colouriser), qui vous permet de colorer la sortie d'un certain nombre de commandes dont diff.

Il s'agit d'un script python qui peut être enroulé autour de n'importe quelle commande. Ainsi, au lieu d'invoquer diff file1 file2, vous invoqueriez grc diff file1 file2pour voir la sortie colorisée. J'ai aliasé diffpour grc diffle rendre plus facile.

dogbane
la source
Ne fonctionne pas sur Windows avec mingw / cygwin en raison d' fork()appels, bien que susceptible de fonctionner avec WSL.
Gabriel Devillers
6

Voici une autre solution qui appelle sedpour insérer les séquences d'échappement ANSI appropriées pour les couleurs pour montrer les +, -et les @lignes en rouge, vert et cyan, respectivement.

diff -u old new | sed "s/^-/$(tput setaf 1)&/; s/^+/$(tput setaf 2)&/; s/^@/$(tput setaf 6)&/; s/$/$(tput sgr0)/"

Contrairement aux autres solutions à cette question, cette solution ne précise pas explicitement les séquences d'échappement ANSI. Au lieu de cela, il appelle les commandes tput setafet tput sgr0pour générer les séquences d'échappement ANSI pour définir une couleur appropriée et réinitialiser les attributs de terminal, respectivement.

Pour voir les couleurs disponibles pour chaque argument tput setaf, utilisez cette commande:

for i in {0..255}; do tput setaf $i; printf %4d $i; done; tput sgr0; echo

Voici à quoi ressemble la sortie:

entrez la description de l'image ici

Voici la preuve que les commandes tput setafet tput sgr0génèrent les séquences d'échappement ANSI appropriées:

$ tput setaf 1 | xxd -g1
00000000: 1b 5b 33 31 6d                                   .[31m
$ tput setaf 2 | xxd -g1
00000000: 1b 5b 33 32 6d                                   .[32m
$ tput setaf 6 | xxd -g1
00000000: 1b 5b 33 36 6d                                   .[36m
$ tput sgr0 | xxd -g1
00000000: 1b 28 42 1b 5b 6d                                .(B.[m
Susam Pal
la source
5

Comme wdiffaccepte les arguments spécifiant la chaîne au début et à la fin des insertions et des suppressions, vous pouvez utiliser des séquences de couleurs ANSI comme chaînes:

wdiff -n -w $'\033[30;41m' -x $'\033[0m' -y $'\033[30;42m' -z $'\033[0m' file1 file2

Par exemple, il s'agit de la sortie de la comparaison de deux fichiers CSV:

sortie diff des fichiers CSV

Exemple de https://www.gnu.org/software/wdiff/manual/html_node/wdiff-Examples.html

jcomeau_ictx
la source
1
colordiffmaintenant (1.0.16) comprend wdiff, vous pouvez donc aussi tout tuyau: wdiff -n f1 f2 | colordiff. wdiffdevrait être fusionné en diffutils ...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
3

Je vous suggère d' essayer diff-so-fancy . Je l'utilise lors de mon travail et ça me semble très bien dès maintenant. Il est livré avec de nombreuses options et il est vraiment facile de configurer vos diffs comme vous le souhaitez.

Vous pouvez l'installer en:

sudo npm install -g diff-so-fancy

ou sur Mac:

brew install diff-so-fancy

Ensuite, vous pouvez mettre en évidence vos différences comme ceci:

diff -u file1 file2 | diff-so-fancy
Naveen
la source
1

Avec la commande bat :

diff file1 file2 | bat -l diff
Jian Weihang
la source
0

Sur les versions récentes de git sur Ubuntu, vous pouvez activer la mise en évidence des différences avec:

sudo ln -s /usr/share/doc/git/contrib/diff-highlight/diff-highlight /usr/local/bin
sudo chmod a+x /usr/share/doc/git/contrib/diff-highlight/diff-highlight

Et puis en ajoutant ceci à votre .gitconfig:

[pager]
    log = diff-highlight | less
    show = diff-highlight | less
    diff = diff-highlight | less

Il est possible que le script se trouve ailleurs dans d'autres distributions, vous pouvez utiliser locate diff-highlightpour savoir où.

rien101
la source
0

Différence de couleur au niveau des caractères: installez ccdiff

ccdiff -r /usr/share/dict/words /tmp/new-dict

Sortie de ccdiff

abricot
la source