Markieren Sie geänderte Zeilen und geänderte Bytes in jeder geänderten Zeile


90

Open Source-Projekt Trac hat einen ausgezeichneten Diff-Textmarker - er hebt geänderte Zeilen und geänderte Bytes in jeder geänderten Zeile hervor! Beispiele finden Sie hier oder hier .

Gibt es eine Möglichkeit, das gleiche Farbhighlight (dh geänderte Zeilen und auch geänderte Bytes ) im Bash-Terminal gitoder vim für die Diff-Ausgabe (Patch-Datei) zu verwenden?


Was möchten Sie hervorheben? Möchten Sie ein Diff-Tool, das die Byteänderungen hervorhebt? (das wäre sehr hilfreich). Sie sagen vim, meiner Erinnerung nach führt vim bereits viele Farbmanipulationen durch, wenn Sie Programmiersprachenvorlagen (und andere) verwenden. Wie würden Sie das ändern? Es gibt eine ganze Reihe von Techniken, um die Farbe in einem Terminalfenster zu ändern, das als VT100 definiert ist (und es gibt Dutzende anderer Definitionen, die auch Farbfluchtsequenzen unterstützen). Weitere Einzelheiten bitte. Oder lesen Sie en.wikipedia.org/wiki/VT100 und verwandte Links. Vielleicht kann das helfen.
Shellter

Ich weiß, dass Sie nur an Open Source-Tools und nur an Terminals interessiert sind. Aber nur als Bezugspunkt möchten Sie vielleicht die Diffzilla von slickedit betrachten. Von den wenigen Diff-Tools, die ich verwendet habe, scheint es immer die besten Zeichenunterschiede darzustellen (obwohl es definitiv Probleme gab, wenn die Unterschiede komplex waren (Kombination aus Formatierung und Codeänderungen, was immer eine schlechte Idee ist)
am


Hinweis: GitHub bietet jetzt ein solches Diff-Tool in seiner Web-GUI an: stackoverflow.com/a/25723584/6309
VonC

Ich habe 'noch eine' reine Git-Diff-Highlight-basierte Lösung mit Tutorials veröffentlicht, um einfach 1) die relevante Diff-Highlight-Datei zu finden, 2) sie ausführbar zu machen 3) die erforderlichen Parameter in .gitconfig festzulegen. Guck dir das mal bitte an. Die Anweisungen gelten für Ubuntu 18.04, sollten jedoch auf Linux-Systemen weitgehend funktionieren.
Zorglub29

Antworten:


56

Das diff-highlightPerl-Contrib-Skript erzeugt eine Ausgabe, die der der Trac-Screenshots so ähnlich ist, dass Trac sie wahrscheinlich verwendet:

Geben Sie hier die Bildbeschreibung ein

Installieren mit:

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

Verschieben Sie die Datei diff-highlightin das ~/bin/Verzeichnis (oder wo immer Sie sich $PATHbefinden) und fügen Sie Folgendes hinzu ~/.gitconfig:

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

Von @cirosantilli vorgeschlagene Installation durch einfaches Kopieren und Einfügen:

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'

Dies. Das ist ausgezeichnet. Danke dir. Es scheint jedoch an einigen Stellen ein wenig konservativ zu sein, da einige Zeilen fehlen, die offensichtlich einen Großteil des Textes gemeinsam haben. Hast du einen Bug Tracker dafür?
naught101

20
Ah, das ist jetzt Teil von Core Git: github.com/git/git/tree/master/contrib/diff-highlight
naught101

2
Es wurde jetzt in ein Modul umgewandelt, und ich denke, die am einfachsten herunterzuladende Version ist die unmittelbar vor dieser Änderung unter raw.githubusercontent.com/git/git/…
Chris Midgley

4
Dieser Teil von Core Git ist nicht nur mit Git verteilt und wahrscheinlich bereits auf Ihrem System vorhanden. Details dazu, wie ich es aktivieren kann, habe ich in meiner Antwort unten hinzugefügt. ↓
Cory Klein

1
Dies vermisst die Unterschiede, die Sie über sehen git add -p. Bitte fügen Sie auch hinzu:git config --global interactive.diffFilter diff-highlight
Josch

40

Verwenden Sie während der Verwendung von git diffoder git logund möglicherweise anderen die Option --word-diff=color(es gibt auch andere Modi für Wortunterschiede übrigens).


2
--word-diff=colorist wirklich besser (besonders mit git config color.diff.old "red reverse"und git config color.diff.new "green reverse"), aber es ist nicht das, was ich will :(
Nikolay Frantsev

4
Was Ihnen also fehlt, ist das Markieren in Farbe / irgendwie sowohl geänderte Zeilen als auch Bytes gleichzeitig?
Anydot

6
Ich möchte geänderte Zeilen und geänderte Bytes in jeder geänderten Zeile hervorheben, wie in Trac. Nicht nur geänderte Bytes, es ist nicht dasselbe.
Nikolay Frantsev

Sie können dies auch verwenden mit git add --patch: stackoverflow.com/questions/10873882/…
naught101

Der Vorteil von diff-highlightist, dass es sowohl für Wortunterschiede als auch für Zeilendifferenzen gut funktioniert.
Ciro Santilli 法轮功 冠状 病 六四 事件 5

20

diff-so-fancyist ein diffTextmarker für menschliche Augäpfel.

Es entfernt die führenden +/ -für das Ausschneiden / Einfügen störenden / und macht klare Abschnitte zwischen Dateien.

Farbig git(links) vs diff-so-fancy(rechts - beachten Sie die Highlights auf Charakterebene):

diff-so-ausgefallene Ausgabe

Wenn Sie die diff-so-fancyAusgabe (auf der rechten Seite) möchten, aber nicht auf Dateien in einem gitRepository beschränkt sind, fügen Sie die folgende Funktion hinzu .bashrc, um sie für alle Dateien zu verwenden:

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

Z.B:

dsf original changed-file

Charakter Level - Hervorhebung und diffStandardformat

Wenn Sie die nicht standardmäßige Formatierung von nicht mögen diff-so-fancy, aber dennoch eine gitHervorhebung auf Zeichenebene wünschen , verwenden Sie diff-highlightdiese, um gitdie Ausgabe zu übernehmen und die wirklich hübsche diffAusgabe im Standardformat zu erstellen:

Screenshot mit diff-Highlight

Um es standardmäßig von zu verwenden git, fügen Sie Folgendes hinzu .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

Der [pager]Abschnitt weist Sie gitan, die bereits farbige Ausgabe an diff-highlightdie Farbe auf Zeichenebene weiterzuleiten und die Ausgabe dann in weniger (falls erforderlich) zu paginieren, anstatt nur die Standardeinstellung zu verwenden less.


Das ist sehr interessant. Können Sie uns etwas über diese gitconfigOptionen erklären ?
Caesarsol

Aktualisiert, auch Funktion hinzugefügt dsf().
Tom Hale

14

Das gewünschte Verhalten ist jetzt in git selbst verfügbar (wie in einem Kommentar von naught101 ausgeführt). Um es zu aktivieren, müssen Sie Ihren Pager auf einstellen

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

Wo /usr/share/doc/git/contrib/diff-highlight/diff-highlightbefindet sich das Textmarkerskript unter Ubuntu 13.10 (ich habe keine Ahnung, warum es sich in einem docOrdner befindet). Wenn es auf Ihrem System nicht vorhanden ist, versuchen Sie es mit locate diff-highlightzu finden. Beachten Sie, dass das Hervorhebungsskript nicht ausführbar ist (zumindest auf meinem Computer), daher ist dies erforderlich perl.

Um den Textmarker immer für die verschiedenen diff-ähnlichen Befehle zu verwenden, fügen Sie Ihrer ~/.gitconfigDatei einfach Folgendes hinzu :

[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

Ich habe dies als neue Antwort hinzugefügt. Der Kommentar von naught101 ist begraben und weil das Setup nicht ganz so trivial ist, wie es sein sollte, und zumindest in der Ubuntu-Version, dass ich die Anweisungen in der README-Datei habe, funktioniert es nicht.


Ich habe gerade bemerkt, dass dies die Hervorhebung für die Unterschiede innerhalb git add -p(interaktiver Modus) nicht aktiviert . Ich weiß jedoch nicht, wie das behoben werden kann. Durch einfaches Hinzufügen von add zur Liste bleibt es hängen.
Dshepherd

5
Dies sollte jetzt in Git 2.9.0 funktionieren:git config interactive.diffFilter diff-highlight
Thomas

^ Das! Leider diff-highlightwar ich nicht auf meinem Weg, also musste ich es zuerst finden. Details in meiner Antwort unten.
Cory Klein

11

Ein Dienstprogramm für bytebasierte Diffs wird seit Version 1.7.8 1 mit offiziellem Git vertrieben . Sie müssen nur herausfinden, wo es auf Ihrem Computer installiert ist, und es aktivieren.

Finden Sie heraus, wo Git installiert ist

  • MacOS mit Git über Homebrew installiert : Es ist/usr/local/opt/git
  • Windows mit Git für Windows : Ausführen cd / && pwd -W, um das Installationsverzeichnis zu finden.
  • Linux: Nerd. Wenn Sie noch nicht wissen, wo Git installiert ist, dann ll $(which git)oder locate gitsollten Sie helfen.

Verknüpfen Sie diff-highlightIhr bin-Verzeichnis, damit Ihr PATH es finden kann

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'

Aktivieren Sie es in Ihrer Git-Konfiguration

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 Hier ist die Version 1.7.8 , aber seitdem wurden viele Änderungen vorgenommen.


1
Es wäre gut anzugeben, in welcher Version es mit git verteilt wurde. Ich vermute auch, dass Distributionen es standardmäßig in PATH setzen, so dass der Symlink-Schritt nicht benötigt wird? Und which giterfordert, dass es in erster Linie
Ciro Santilli 12 冠状 病 六四 事件 法轮功

2
Es wäre gut! Fühlen Sie sich frei, diese Informationen hinzuzufügen. Und obwohl Git bündelt diff-highlight, installiert es es nicht wirklich , so dass der Symlink-Schritt tatsächlich notwendig ist (zumindest unter macOS). Wenn Sie feststellen, dass dies für Ihre Plattform nicht erforderlich ist, können Sie die Antwort erneut aktualisieren. Inzwischen which githat in der Regel arbeiten, weil Git tut die Installation von gitbinären irgendwo auf dem Weg.
Cory Klein

Beachten Sie, dass ich in debian unstable diese Datei "kompilieren" musste, weil ich gerade eine hatte .perl. Die Kompilierung ist trivial: einfach sudo makeim diff-highlightVerzeichnis ausführen .
tobiasBora

10

Ich benutze --color-wordsOption und es funktioniert gut für mich:

$ git diff --color-words | less -RS

5
Nein, dies zeigt nur den Unterschied in Worten. Was das OP (und ich) wollen, ist ein normaler zeilenweiser Unterschied, wobei die Wortunterschiede hervorgehoben sind (sagen wir, verschiedene Zeilen sind farbiger Text, und die Wortunterschiede innerhalb dieser Zeilen sind normaler farbiger Text mit farbiger Hervorhebung oder etwas). Siehe die Beispiellinks jetzt in der Frage.
naught101

1
pastebin.com/1JrhYHRt Eigentlich verwende ich vimdiff als Difftool und vimdiff mit Molokai-Farbschema, um eine schöne Hervorhebung zu erhalten, wie Sie in Ihrer Frage beschreiben. 1- git config --global diff.tool vimdiff 2- in vim ": colo molokai" * Molokai @ github.com/tomasr/molokai * Mögliches automatisches Farbschema mit ~ / .vimrc: if & diff set background = dunkles Farbschema molokai endif
amized

4

wie @dshepherd sagt :

Das gewünschte Verhalten ist jetzt in Git selbst verfügbar

Befindet diff-highlightsich aber in DOC und ist nicht über die Shell erhältlich.
Führen diff-highlightSie ~/bindie folgenden Schritte aus, um die Installation in Ihrem Verzeichnis durchzuführen (dies spart Ihre Eingabe):

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

Dann konfigurieren Sie Ihr .gitconfigals offizielles Dokument sagt:

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

UPD
Auch können Sie als nächstes spätestens gitohne Installation versuchen :

git diff --color-words=.

Komplexer:

git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'

1

Emacs verfügt über die Ediff-Patch-Buffer-Funktion, die Ihre Anforderungen erfüllen sollte.

Öffnen Sie die nicht gepatchte Datei in emacs Typ ESC-x, ediff-patch-buffer.

Befolgen Sie die Anweisungen, und Sie sollten einen hervorgehobenen Vergleich der gepatchten und der Originalversion Ihrer Datei sehen.

Gemäß Ihrem Kommentar erhalten Sie im Folgenden eine Bash-Lösung, für die nur dwdiff erforderlich ist:

#!/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

Entschuldigung, ich möchte keine Emacs verwenden, nur Bash, Git oder Vim
Nikolay Frantsev

Das ist verständlich. Das einzige andere, was mir einfällt, ist die Verwendung von colordiff mit dem stdout von patch: colordiff -u <(patch original_file -i patch_file -o -) <(cat original_file) aber dies wird nur geänderte Zeilen hervorheben, keine Bisse ...
Finbar Crago

Ich habe über Ihr Problem etwas mehr nachgedacht und eine zweite Lösung angehängt, die nur dwdiff erfordert.
Finbar Crago

1
Bitte lesen Sie meine Frage sorgfältig durch, ich möchte keine Dateien vergleichen
Nikolay Frantsev

1
Entschuldigen Sie die Verwirrung. Sie möchten also die geänderten Bytes in den geänderten Zeilen einer Diff-Datei hervorheben? Wenn ja, versuchen Sie esdwdiff -c --diff-input diff_file
Finbar Crago

1

Diffy

GitLab verwendet Diffy https://github.com/samg/diffy (Ruby), um eine Ausgabe ähnlich GitHub und Diff-Highlight zu erzielen:

Geben Sie hier die Bildbeschreibung ein

Diffy erstellt das Diff selbst mit demselben Algorithmus und Git und unterstützt verschiedene Arten von Ausgaben, einschließlich der von GitLab verwendeten HTML-Ausgabe:

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

Ausgabe:

<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>

Beachten Sie, wie strongzu den geänderten Bytes hinzugefügt wurde.


0

Ja, Vim tut dies einschließlich der Hervorhebung von Text, der innerhalb einer Zeile geändert wurde.
Sehen :h diffund :h 08.7für weitere Informationen, wie man diff - Dateien.

Vim verwendet einen ziemlich einfachen Algorithmus zum Hervorheben. Es durchsucht die Zeile nach dem ersten geänderten Zeichen und dann nach dem zuletzt geänderten Zeichen und hebt einfach alle Zeichen zwischen ihnen hervor.
Dies bedeutet, dass Sie nicht mehrere Highlights pro Zeile haben können - viele Designentscheidungen in Vim priorisieren die Effizienz.


Leider werden geänderte Bytes in der Diff-Ausgabe nicht hervorgehoben (Dateityp = Diff setzen)
Nikolay Frantsev

1
Ich glaube, ich verstehe Ihre Frage jetzt - Sie möchten die Textausgabe des Befehls diff so syntaktisch hervorheben, dass alle innerhalb einer Zeile vorgenommenen Änderungen hervorgehoben werden. Wenn Sie diesen Text in Vim bearbeiten, werden Linienunterschiede hervorgehoben, nicht jedoch die innerhalb einer Linie vorgenommenen Änderungen.
PDug

Könnten Sie den Befehl Vim's: patchfile verwenden, um die Originaldatei zu laden und sie dann mit der gepatchten Version zu vergleichen?
PDug

Leider nein, ich möchte die rekursive Diff-Ausgabe für mehrere Dateien verwenden
Nikolay Frantsev

0

vimdiff file1 file2 zeigt den Unterschied zwischen zwei Dateien zeichenweise an.

vimdiff ist ein Diff-Tool, das in vim enthalten ist. (Vim sollte mit der Option + diff kompiliert worden sein, um sicherzugehen, dass Sie dies überprüfen können. :version)

Sie können es auch von vim aus starten. Siehe :help difffür weitere Informationen und Befehle.


Ich möchte keine Dateien vergleichen, ich möchte eine diff (Patch) -Datei hervorheben.
Nikolay Frantsev

@Nikolay Frantsev Wenn Sie sich nicht für Leistung interessieren, können Sie mein format.vim- Plugin installieren und tun vimdiff file.old file.new -c 'FormatCommand diffformat' -c 'w! file.diff.html' -c 'qa!'.
ZyX

Es wird einen Unterschied in einem Batch-Modus machen (voranstellen screen -D -moder anhängen &>/dev/null(/ dev / null-Variante erzeugt manchmal seltsame Fehler), wenn Sie nicht möchten, dass das Terminal blinkt) und vim beenden, nachdem die Formatierung abgeschlossen ist, aber es ist reines vimscript und Trotz meiner Optimierungen ist es für große Dateien sehr langsam.
ZyX

0

Hinweis : Dies ist ein Duplikat dessen, was hier zu finden ist: Wie kann die Diff-Hervorhebung von Git verbessert werden? . Ich poste meine Antwort auch hier, da es für einige Leute hilfreich sein kann, die diesen Thread direkt finden :)

Wie in einigen früheren Antworten gesagt, ist dies nur mit Git-Sachen möglich. Ich poste dies, da die Anweisungen je nach System möglicherweise etwas einfacher zu befolgen sind, dies ähnelt jedoch mehreren anderen Antworten.

Eine Lösung, die sich ausschließlich auf Git und seine Beiträge stützt. Dies erfordert keine zusätzlichen Dateien als die, die mit git geliefert werden . Alle Erklärungen beziehen sich auf Ubuntu (getestet am 18.04LTS) und sollten auf anderen Linux-Systemen ähnlich funktionieren:

  • Suchen Sie das Diff-Highlight-Contrib-Git-Snippet:
find -L /usr -name diff-highlight -type f

Auf meinem System lautet die einzig gültige Antwort:

/usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Machen Sie das entsprechende Perl-Skript ausführbar. In meinem Fall musste ich tun:
sudo chmod +x /usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Aktualisieren Sie Ihre ~/.gitconfig, um das gewünschte Ergebnis zu erhalten, indem Sie hinzufügen (beachten Sie, dass dies TABS und keine 4 Leerzeichen sind):
[color "diff-highlight"]
    oldNormal = red
    oldHighlight = red 52
    newNormal = green
    newHighlight = green 22
  • Genießen Sie das Ergebnis (Hinweis: Dies ist nur für die Diff-Färbung + Hervorhebung, ich habe hier auch andere Dinge für die Eingabeaufforderung im Spiel :)).

diff-highligh

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.