Mettez en surbrillance les lignes modifiées et les octets modifiés dans chaque ligne modifiée

91

Le projet Open Source Trac a un excellent surligneur de diff - il met en évidence les lignes modifiées et les octets modifiés dans chaque ligne modifiée! Voir ici ou ici pour des exemples.

Existe-t-il un moyen d'utiliser la même couleur de surbrillance (c'est-à-dire les lignes modifiées et les octets modifiés aussi ) dans le terminal bash git, ou vim pour la sortie diff (fichier patch)?

Nikolay Frantsev
la source
Qu'est-ce que vous souhaitez mettre en évidence? Voulez-vous un outil de comparaison qui met en évidence les modifications d'octets? (Ce serait très utile). Vous dites vim, si je me souviens bien, vim fait déjà beaucoup de manipulation de couleurs lorsque vous utilisez des modèles de langage de programmation (et autres). Comment changeriez-vous cela? Il existe de nombreuses techniques disponibles pour changer de couleur sur une fenêtre de terminal définie par VT100 (et il existe des dizaines d'autres définitions qui prendront également en charge les séquences d'échappement de couleur). Plus de détails s'il vous plaît. Ou lisez en.wikipedia.org/wiki/VT100 et les liens connexes. Peut-être que cela peut aider.
shellter
Je sais que vous ne vous intéressez qu'aux outils open source, et uniquement aux terminaux. Mais juste comme point de référence, vous voudrez peut-être regarder le diffzilla de slickedit. des quelques outils de diff que j'ai utilisés, il semble toujours représenter le mieux les différences de caractères (bien qu'il ait certainement eu des problèmes lorsque les diffs étaient complexes (combinaison de mise en forme et de code change, ce qui est toujours une mauvaise idée)
nhed
On dirait un dup de stackoverflow.com/questions/3231759/…
Adam Monsen
Remarque: GitHub propose désormais un tel outil de
comparaison
J'ai posté 'encore' une autre solution pure git, basée sur diff-highlight avec des tutoriels pour 1) trouver facilement le fichier de diff-highlight pertinent, 2) le rendre exécutable 3) définir les paramètres nécessaires dans .gitconfig. Jetez un coup d'oeil s'il vous plait. Les instructions concernent Ubuntu 18.04 mais devraient fonctionner globalement sur les systèmes Linux.
Zorglub29

Réponses:

57

Le diff-highlightscript de contribution Perl produit une sortie si similaire à celle des captures d'écran Trac qu'il est probable que Trac l'utilise:

entrez la description de l'image ici

Installer avec:

wget https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight && chmod +x diff-highlight

Déplacez le fichier diff-highlightdans le ~/bin/répertoire (ou où que vous soyez $PATH), puis ajoutez ce qui suit à votre ~/.gitconfig:

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

Installation simple copier-coller suggérée par @cirosantilli:

cd ~/bin
curl -O https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight
chmod +x diff-highlight
git config --global pager.log 'diff-highlight | less'
git config --global pager.show 'diff-highlight | less'
git config --global pager.diff 'diff-highlight | less'
Sina Samavati
la source
Ce. C'est excellent. Je vous remercie. Cela semble être un peu conservateur à certains endroits cependant, manquant certaines lignes qui ont évidemment une majorité de texte en commun. Avez-vous un bug tracker pour cela?
naught101
20
Ah, cela fait partie du noyau git maintenant: github.com/git/git/tree/master/contrib/diff-highlight
naught101
2
Il a maintenant été transformé en module, et je pense que la version la plus simple à télécharger est celle qui a précédé immédiatement ce changement sur raw.githubusercontent.com/git/git
Chris Midgley
4
Non seulement cette partie du core git, elle est distribuée avec git et probablement déjà sur votre système. J'ai ajouté des détails sur la façon de l'activer dans ma réponse ci-dessous. ↓
Cory Klein
1
Cela manque les diffs que vous voyez via git add -p. Veuillez également ajouter:git config --global interactive.diffFilter diff-highlight
josch
40

Lors de l'utilisation de git diffou git loget éventuellement d'autres, utilisez l'option --word-diff=color(il existe également d'autres modes pour les différences de mots BTW)

anydot
la source
2
--word-diff=colorc'est vraiment mieux (surtout avec git config color.diff.old "red reverse"et git config color.diff.new "green reverse"), mais ce n'est pas ce que je veux :(
Nikolay Frantsev
4
Donc, la seule chose qui vous manque est le marquage en couleur / en quelque sorte les lignes et les octets modifiés en même temps?
anydot
6
Je veux mettre en évidence les lignes modifiées et les octets modifiés dans chaque ligne modifiée, comme dans Trac. Pas seulement des octets modifiés, ce n'est pas la même chose.
Nikolay Frantsev
Vous pouvez également l'utiliser avec git add --patch: stackoverflow.com/questions/10873882/…
naught101
L'avantage de diff-highlightest qu'il fonctionne bien pour les différences de mots et de lignes.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
20

diff-so-fancyest un diffsurligneur conçu pour les globes oculaires humains.

Il supprime les +/ -qui sont gênants pour le copier / coller et rend les sections claires entre les fichiers.

Couleur git(gauche) vs diff-so-fancy(droite - notez les surbrillances au niveau des caractères):

sortie diff-so-fantaisie

Si vous voulez la diff-so-fancysortie (côté droit) mais pas contrainte aux fichiers dans un gitréférentiel, ajoutez la fonction suivante à votre .bashrcpour l'utiliser sur n'importe quel fichier:

dsf() { git diff --no-index --color "$@" | diff-so-fancy; }

Par exemple:

dsf original changed-file

Mise en évidence au niveau des caractères et diffformat standard

Si vous n'aimez pas le formatage non standard de diff-so-fancy, mais que vous voulez quand même la gitmise en évidence au niveau des caractères , utilisez diff-highlightqui prendra gitla sortie de et produira la diffsortie au format standard vraiment jolie :

capture d'écran diff-highlight

Pour l'utiliser par défaut depuis git, ajoutez à votre .gitconfig:

[color "diff-highlight"]
  oldNormal = red bold
  oldHighlight = red bold 52
  newNormal = green bold
  newHighlight = green bold 22

[pager]
  diff = diff-highlight | less -FRXsu --tabs=4

La [pager]section indique gitde diriger sa sortie déjà colorée vers les diff-highlightcouleurs au niveau du caractère, puis page la sortie en moins (si nécessaire), plutôt que d'utiliser simplement la valeur par défaut less.

Tom Hale
la source
C'est très intéressant, pourriez-vous expliquer un peu ces gitconfigoptions?
caesarsol
Mis à jour, ajoutant également une fonction dsf().
Tom Hale
14

Le comportement souhaité est désormais disponible dans git lui-même (comme cela a été souligné dans un commentaire de naught101). Pour l'activer, vous devez régler votre téléavertisseur sur

perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

/usr/share/doc/git/contrib/diff-highlight/diff-highlightest l'emplacement du script de surligneur sur Ubuntu 13.10 (je n'ai aucune idée de pourquoi il est dans un docdossier). S'il n'est pas présent sur votre système, essayez d'utiliser locate diff-highlightpour le trouver. Notez que le script de mise en évidence n'est pas exécutable (du moins sur ma machine), d'où l'exigence de perl.

Pour toujours utiliser le surligneur pour les différentes commandes de type diff, ajoutez simplement ce qui suit à votre ~/.gitconfigfichier:

[pager]
    log = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    show = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    diff = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

J'ai ajouté cela comme une nouvelle réponse, le commentaire de naught101 est enterré et parce que la configuration n'est pas aussi triviale qu'elle devrait l'être et au moins sur la version d'Ubuntu que j'ai les instructions dans le README ne fonctionnent pas.

dshepherd
la source
Je viens de remarquer que cela n'active pas la mise en évidence des différences dans git add -p(mode interactif). Je ne sais pas comment cela peut être corrigé, le simple fait d'ajouter un ajout à la liste le bloque.
dshepherd
5
Cela devrait fonctionner maintenant dans git 2.9.0:git config interactive.diffFilter diff-highlight
Thomas
^ Ceci! Malheureusement, ce diff-highlightn'était pas sur mon chemin, j'ai donc dû d'abord le localiser. Détails dans ma réponse ci-dessous.
Cory Klein
11

Un utilitaire pour les différences basées sur les octets a été distribué avec Git officiel depuis la v1.7.8 1 . Il vous suffit de localiser où il est installé sur votre machine et de l'activer.

Trouvez où Git est installé

  • MacOS avec Git installé via Homebrew : c'est/usr/local/opt/git
  • Windows avec Git pour Windows : exécutez cd / && pwd -Wpour trouver le répertoire d'installation.
  • Linux: Nerd. Si vous ne savez pas déjà où Git est installé, alors ll $(which git)ou locate gitdevrait vous aider.

Lien diff-highlightvers votre répertoire bin afin que votre PATH puisse le trouver

GIT_HOME='/usr/local/opt/git/'  # Use the value from the first step.
ln -s "${GIT_HOME}/share/git-core/contrib/diff-highlight/diff-highlight" \
      '/usr/local/bin/diff-highlight'

Activez-le dans votre configuration Git

git config --global interactive.diffFilter diff-highlight # Use on interactive prompts
git config --global pager.diff "diff-highlight | less"    # Use on git diff
git config --global pager.log  "diff-highlight | less"    # Use on git log
git config --global pager.show "diff-highlight | less"    # Use on git show

1 Voici la version v1.7.8 , mais de nombreux changements ont été apportés depuis.

Cory Klein
la source
1
Il serait bon de spécifier dans quelle version il a commencé à être distribué avec git. Je suppose également que les distributions le mettront dans PATH par défaut, donc l'étape de lien symbolique ne sera pas nécessaire? Et which gitexige qu'il soit dans le PATH en premier lieu, donc cela ne fonctionnera pas si ce n'est pas :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
Ce serait bien! N'hésitez pas à ajouter ces informations. Et bien que Git le bundle diff-highlight, il ne l' installe pas réellement , donc l'étape de lien symbolique est en effet nécessaire (au moins sur macOS). Si vous trouvez que cela n'est pas nécessaire pour votre plate-forme, n'hésitez pas à mettre à jour la réponse. Pendant ce temps, which gitne fonctionne généralement, parce que Git fait installer gitquelque part sur le chemin binaire.
Cory Klein
Notez que dans debian unstable j'avais besoin de "compiler" ce fichier, car j'avais juste un fichier .perl. La compilation est triviale: il suffit de l'exécuter sudo makedans le diff-highlightrépertoire.
tobiasBora le
10

J'utilise l' --color-wordsoption et cela fonctionne bien pour moi:

$ git diff --color-words | less -RS
amized
la source
5
Non, cela ne montre que la différence entre les mots. Ce que l'OP (et moi) voulons, c'est un diff normal ligne par ligne, avec les différences de mots en surbrillance (donc, disons que différentes lignes sont du texte coloré, et que les différences de mots à l'intérieur de ces lignes sont du texte de couleur normal, avec une surbrillance colorée ou quelque chose). Voir les exemples de liens maintenant dans la question.
naught101
1
pastebin.com/1JrhYHRt En fait, j'utilise vimdiff comme difftool et vimdiff avec molokai colorscheme pour obtenir une belle mise en évidence comme vous le décrivez dans votre question. 1- git config --global diff.tool vimdiff 2- dans vim ": colo molokai" * Molokai @ github.com/tomasr/molokai * Possible auto colourcheme avec ~ / .vimrc: if & diff set background = dark colorscheme molokai endif
amisé le
4

comme le dit @dshepherd :

Le comportement souhaité est désormais disponible dans git lui-même

Mais diff-highlightse trouve dans DOC et n'est pas disponible à partir du shell.
Pour installer diff-highlightdans votre ~/binrépertoire, suivez les étapes suivantes (cela enregistrera votre saisie):

$ locate diff-highlight
$ cd /usr/share/doc/git/contrib/diff-highlight  #or path you locate
$ sudo make
$ mv diff-highlight ~/bin

Ensuite, configurez votre .gitconfigdocument officiel comme le dit:

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

UPD
Vous pouvez également essayer la dernière version gitsans aucune installation:

git diff --color-words=.

Plus complexe:

git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
Eugen Konkov
la source
1

Emacs a la fonction ediff-patch-buffer qui devrait répondre à vos besoins.

Ouvrez le fichier non patché dans emacs type ESC-x, ediff-patch-buffer.

Suivez les invites et vous devriez voir une comparaison en surbrillance des versions corrigées et originales de votre fichier.

Selon votre commentaire, ce qui suit vous donnera une solution bash ne nécessitant que dwdiff:

#!/bin/bash
paste -d'\n' <(dwdiff -2 -L -c <(cat $2) <(patch $2 -i $1 -o -)) <(dwdiff -1 -L -c <(cat $2) <(patch $2 -i $1 -o -))| uniq
Finbar Crago
la source
désolé, je ne veux pas utiliser emacs, seulement bash, git ou vim
Nikolay Frantsev
C'est compréhensible. La seule autre chose à laquelle je peux penser est d'utiliser colordiff avec le stdout du patch: colordiff -u <(patch original_file -i patch_file -o -) <(cat original_file) mais cela ne fera que mettre en évidence les lignes modifiées et non les morsures ...
Finbar Crago
J'ai réfléchi un peu plus à votre problème et j'ai ajouté une deuxième solution qui ne nécessite que dwdiff.
Finbar Crago
1
s'il vous plaît lire attentivement ma question, je ne veux pas comparer les fichiers
Nikolay Frantsev
1
désolé pour la confusion, donc votre juste après un moyen de mettre en évidence les octets modifiés sur les lignes modifiées d'un fichier diff? si oui, essayezdwdiff -c --diff-input diff_file
Finbar Crago
1

Diffy

GitLab utilise Diffy https://github.com/samg/diffy (Ruby) pour obtenir une sortie similaire à GitHub et diff-highlight:

entrez la description de l'image ici

Diffy fait le diff lui-même en utilisant le même algorithme ad Git, et prend en charge différents types de sorties, y compris la sortie HTML utilisée par GitLab:

gem install diffy
echo '
  require "diffy"    
  puts Diffy::Diff.new("a b c\n", "a B c\n").to_s(:html)
' | ruby

Production:

<div class="diff">
  <ul>
    <li class="del"><del>a <strong>b</strong> c</del></li>
    <li class="ins"><ins>a <strong>B</strong> c</ins></li>
  </ul>
</div>

Notez comment a strongété ajouté aux octets modifiés.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
0

Oui, Vim fait cela, y compris la mise en évidence du texte modifié dans une ligne.
Voir :h diffet :h 08.7pour plus de détails sur la façon de différencier les fichiers.

Vim utilise un algorithme assez simple pour sa mise en évidence. Il recherche sur la ligne le premier caractère modifié, puis le dernier caractère modifié, et met simplement en surbrillance tous les caractères entre eux.
Cela signifie que vous ne pouvez pas avoir plusieurs points forts par ligne - de nombreuses décisions de conception dans Vim donnent la priorité à l'efficacité.

PDug
la source
malheureusement, il ne met pas en évidence les octets modifiés sur la sortie diff (set filetype = diff)
Nikolay Frantsev
1
Je pense que je comprends votre question maintenant - Vous voulez mettre en évidence la syntaxe de la sortie textuelle de la commande diff afin qu'elle met en évidence toutes les modifications apportées à l'intérieur d'une ligne. La modification de ce texte dans Vim met en évidence les différences de ligne, mais pas les modifications apportées à l'intérieur d'une ligne.
PDug
Pourriez-vous utiliser la commande Vim's: patchfile pour charger le fichier original et le comparer à la version corrigée?
PDug
malheureusement non, je souhaite utiliser une sortie diff récursive pour plusieurs fichiers
Nikolay Frantsev
0

vimdiff file1 file2 affichera la différence par caractère entre deux fichiers.

vimdiff est un outil de diff inclus dans vim. (Vim aurait dû être compilé avec l'option + diff, pour être sûr que vous pouvez vérifier avec :version)

Vous pouvez également le lancer depuis l'intérieur de vim. Voir :help diffpour plus d'informations et de commandes.

Xavier T.
la source
Je ne veux pas comparer les fichiers, je veux mettre en évidence le fichier diff (patch).
Nikolay Frantsev
@Nikolay Frantsev Si vous ne vous souciez pas de la performance, vous pouvez installer mon plugin format.vim et le faire vimdiff file.old file.new -c 'FormatCommand diffformat' -c 'w! file.diff.html' -c 'qa!'.
ZyX
Il fera un diff en mode batch (préfixer screen -D -mou ajouter &>/dev/null(la variante / dev / null produit parfois des bogues étranges) si vous ne voulez pas voir le terminal clignoter) et quitter vim une fois le formatage terminé, mais c'est du pur vimscript et même avec mes optimisations, il est très lent pour les gros fichiers.
ZyX
0

Remarque : ceci est une copie de ce qui se trouve ici: Comment améliorer la mise en évidence des différences de git? . Publier ma réponse ici aussi, car cela peut être utile à certaines personnes qui trouvent directement ce fil :)

Comme indiqué dans certaines réponses précédentes, cela n'est possible qu'avec des trucs git. Je poste ceci car les instructions peuvent être un peu plus faciles à suivre en fonction de votre système, mais cela est similaire à plusieurs autres réponses.

Une solution qui repose uniquement sur git et ses contributions. Cela ne nécessite aucun fichier supplémentaire que celui fourni avec git . Toutes les explications sont pour Ubuntu (testé sur 18.04LTS), devraient fonctionner de la même manière sur les autres systèmes Linux:

  • Localisez l'extrait de git contrib diff-highlight:
find -L /usr -name diff-highlight -type f

sur mon système, la seule réponse valable est:

/usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Rendez le script perl correspondant exécutable. Dans mon cas, je devais faire:
sudo chmod +x /usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Mettez ~/.gitconfigà jour votre pour obtenir le résultat souhaité, en ajoutant (notez qu'il s'agit de TABS et non de 4 espaces):
[color "diff-highlight"]
    oldNormal = red
    oldHighlight = red 52
    newNormal = green
    newHighlight = green 22
  • Profitez du résultat (note: ce n'est que pour la coloration diff + le surlignage, j'ai d'autres choses en jeu ici aussi pour l'invite bien sûr :)).

diff-highligh

Zorglub29
la source