Git diff, um nur Zeilen anzuzeigen, die geändert wurden

127

Wenn ich ein Git-Diff mache, werden Linien hinzugefügt, die hinzugefügt wurden:

+ this line is added

Linien, die entfernt wurden:

- this line is removed

es werden aber auch viele Zeilen angezeigt, die nicht geändert werden:

this line is not modified
this line is also not modified

Dies führt dazu, dass der tatsächliche Git-Diff ungefähr so ​​aussieht:

+ this line is added
  this line is not modified
- this line is removed
  this line is not modified

Kann ich git bitten, nur geänderte Zeilen anzuzeigen und den gesamten anderen Code zu ignorieren, der nicht geändert wurde? Ich habe eine Methode geschrieben, mit der alle Zeilen entfernt werden, vor denen kein "+" oder "-" steht, aber ich bin sicher, dass es einen einfacheren Weg geben muss, dies zu tun.

In meinem Git Diff bin ich nur daran interessiert, die Zeilen zu sehen, die geändert wurden.

Danke im Voraus.

r3b00t
quelle

Antworten:

181

Was Sie wollen, ist ein Diff mit 0 Kontextzeilen. Sie können dies generieren mit:

git diff --unified=0

oder

git diff -U0

Sie können dies auch als Konfigurationsoption für dieses Repository festlegen:

git config diff.context 0

Um es global für jedes Repository festzulegen:

 git config --global diff.context 0
Chris Hayes
quelle
4
Danke für Ihre schnelle Antwort. Dies löst die Hälfte meines Problems, aber ich erhalte immer noch einige Zeilen wie "@@ -1 +1 @@" in meinem Diff und oben in meinem Git-Diff "diff --git a / db / xxxxxxx b / db / xxxx-Index xxxxx..aaaaaaa bbbbbbbb
r3b00t
3
Ich glaube nicht, dass Git eine Möglichkeit bietet, die Ausgabe dieser Zeilen zu vermeiden, da der Unterschied ohne sie keinen Sinn ergeben würde (Sie konnten nicht wissen, welche Datei Sie sich angesehen haben oder wo Sie sich in der Datei befanden).
Chris Hayes
8
@Rakesh: Um zu erweitern, versucht git-diff, Unterschiede zu erstellen, die tatsächlich als Patches für Quelldateien verwendet werden können, was ohne diese Informationen nicht möglich ist. Die einzige Möglichkeit, es zu entfernen, besteht darin, es selbst nachzubearbeiten, z. B. über git diff | egrep "^(\+|-) ".
Chris Hayes
1
git config --global diff.context 0 um es global einstellen zu lassen
Andrzej Rehmann
Wenn Sie in einem bestimmten Verzeichnis sehen möchten, versuchen Sie git diff -U0 <dir>
Eswar Yaganti
40

Ein weiterer Hack (auf un * x), um nur die Zeilen anzuzeigen, die mit +und beginnen -:

git diff -U0 | grep '^[+-]' | grep -Ev '^(--- a/|\+\+\+ b/)'

Der obige Code bewirkt Folgendes:

  • git diff -U0: Wählen Sie 0 Kontextzeilen
  • Der erste grep enthält nur alle Zeilen, die mit +oder beginnen-
  • Der zweite Grep schließt Zeilen aus, die mit --- a/oder beginnen+++ b/

Farbe

Versuchen Sie Folgendes, um farbige Unterschiede anzuzeigen:

git diff -U0 --color | grep '^\e\[[^m]*m[-+]' | grep -Ev '(--- a/|\+\+\+ b/)'
  • Der Ausdruck ,, ^\e\[[^m]*m[-+]sucht nach dem Anfang von Zeile ( ^), dann nach dem Escape-Zeichen ( \e), gefolgt von [dem gemeinsamen Start der Escape-Sequenz, dann nach jedem Zeichen, das kein "m" ist (Zahlen, Semikolons oder nichts), gefolgt von einem " m ", wodurch die Escape-Sequenz beendet wird.
  • Beachten Sie, dass alle folgenden gültigen Escape-Sequenzen sind: \e[0m(Zurücksetzen), \e[m(auch Zurücksetzen), \e[1m(Fettdruck), \e[31m(Rot), \e[32m(Grün), \e[9;31m(Durchgestrichen + Rot), \e[31;9m(Rot + Durchgestrichen), \e[1;4;9;31m(Fett + unterstreichen + streichen + rot). Die Standard-Git-Farben verwenden Rot und Grün, können jedoch neu konfiguriert werden.
  • --colorist das gleiche wie --color=always.
  • Die Einschränkung für --- a/oder +++ b/am Anfang der Zeile wurde entfernt, um die Escape-Sequenzen zu berücksichtigen, und dies könnte zu einem Randfall führen.

Zusätzliche Bemerkungen:

  • Die obige Lösung muss geändert werden , wenn Sie zusätzliche git diff - Optionen verwenden wie -R, --src-prefix, --dst-prefix, --no-prefix, usw.
  • Die beiden Greps können zu einem einzigen kombiniert werden grep -E -v '^(\+\+\+ b/|--- a/|@@ |diff --git|index )', aber ich finde die Double Grep-Version leichter zu verstehen.
user650654
quelle
2
Schön. Stimmen Sie für die klare Erklärung zu jedem Filter ab.
Henrebotha
Ich sehe viele git diffZeilen vom Typ "Header", die mit beginnen @@, aber was sind git diffZeilen, die mit ---oder beginnen +++? Ich war mir dieser nicht bewusst.
Gabriel Staples
Ah vergiss es. Diese bezeichnen Dateinamen für Dateien, die additions ( +++) oder deletions ( ---) enthalten. Ich sehe das jetzt hier: git-scm.com/docs/git-diff#_combined_diff_format .
Gabriel Staples
Korrektur noch einmal: --- a/filenameScheint die "Datei links" oder die Datei wie zuvor +++ b/filenamezu bezeichnen und scheint die "Datei rechts" oder die Datei zu bezeichnen, wie sie jetzt mit Ihren Änderungen ist. Ich bin es so gewohnt, git difftoolmit meld zu arbeiten , das schöne Vergleiche nebeneinander zeigt, dass ich mich nie wirklich daran gewöhnt habe, es anzuschauen git diff, also sieht es für mich immer noch seltsam aus, und ich habe diese Nuancen noch nie wirklich angeschaut.
Gabriel Staples
1
@ GabrielStaples, Unterstützung für Farbe wurde hinzugefügt. Vielen Dank.
user650654
6

Nach Chris 'jüngstem Kommentar besteht das Hauptproblem bei der Nachbearbeitung darin, dass Sie die Zeilen am Anfang halten möchten, -|+aber auch diejenigen herausfiltern möchten, die mit beginnen ---|+++. Wenn Sie Patch-Dateien in Ihrem Repo speichern (ich in Pydoop ), möchten Sie andererseits Zeilen --|++beibehalten , die mit beginnen , damit der reguläre Ausdruck ein wenig kompliziert wird:

git diff | grep -P '^\+(?:(?!\+\+))|^-(?:(?!--))'

Der reguläre Ausdruck verwendet einen negativen Lookahead: Eine ausführliche Erklärung finden Sie in der Antwort von Peter Boughton auf diese Frage .

Wenn Sie dies häufig tun, möchten Sie möglicherweise einen Git-Alias ​​dafür einrichten:

git config --global alias.diffonly '!git diff | grep -P "^\+(?:(?!\+\+))|^-(?:(?!--))"'
simleo
quelle
1
Dies funktionierte nicht für mich unter Windows Git Bash. Ich weiß nicht warum (grep sagte ungültige Option P), habe im Moment nicht die Chuzpe, um sie zu untersuchen.
Dennis
1
-Poder --perl-regexpwird verwendet, um das Muster als regulären Perl-Ausdruck zu interpretieren, wird jedoch nicht immer implementiert. Unter OSX hat es bei mir nicht funktioniert. gnu.org/software/grep/manual/grep.html#grep-Programs
Willington Vega
4

Ich denke, in einfachen Fällen kann der reguläre Ausdruck viel kürzer und leichter zu merken sein, mit der Einschränkung, dass dies nicht funktioniert, wenn Sie Linienänderungen haben, bei denen die Linie selbst mit +oder beginnt-

$ git diff | grep '^[+|-][^+|-]'

Die Regex sagt, dass die Zeile mit +oder beginnen -sollte und das unmittelbar folgende Zeichen keines von diesen sein sollte. Ich habe die gleichen Ergebnisse erzielt, ob ich hier entkommen bin +oder nicht, übrigens ...


Beispiel:

$ cat testfile
A
B
C
D
E
F
G

Sagen wir, ich wechsle Czu X, Ezu Yund Gzu Z.

$ git diff | grep '^[+|-][^+|-]'
-C
+X
-E
+Y
-G
+Z

Wie ich oben sagte, ist dies jedoch nur für die meisten Fälle. Wenn Sie diese Ausgabe an eine Datei doutweiterleiten und denselben regulären Ausdruck verwenden, funktioniert dies nicht.

$ git diff dout | grep '^[+|-][^+|-]'
$

Wie auch immer, hoffe das hilft in deinem Fall

Galois
quelle
In Fällen, in denen die Zeile mit "-" beginnt, funktioniert sie nicht. Beispiel: - name: No pdbIn einer Yaml-Datei.
Anapaulagome
3

Diese Antwort behält die ursprünglichen rot / grünen Farben zur besseren Lesbarkeit bei. Ich habe einige Variationen in der Syntax angegeben:

git diff --color | grep --color=never $'^\e\[3[12]m'
git diff --color | grep --color=never $'^\033\[3[12]m'
git diff --color | grep --color=never -P '^\e\[3[12]m'
git diff --color | grep --color=never -P '^\033\[3[12]m'

Erläuterung:

  • Das git diff --colorist notwendig , git , um zu verhindern , die Farbe zu deaktivieren , wenn es kochend.
  • Das grep --color=neversoll verhindern , grep die ursprüngliche Farbe zu entfernen und Hervorhebung der gefundenen String.
  • Wir stimmen für Zeilen überein, die mit roten ( \e[31m) oder grünen ( \e[32m) Escape-Codes beginnen.
  • Die $'...'(ANSI-C-Anführungszeichen-Syntax) oder -P(Perl-Syntax) ist grepzu interpretieren \eoder \033als ESCZeichen.
wisbucky
quelle
Danke dafür. Hier ist eine alternative Form, die ich mir gerade ausgedacht habe. Ihr $''Teil hat mir besonders geholfen. stackoverflow.com/a/61929887/4561887
Gabriel Staples
1

So verwenden Sie awknur die +und --Linien unter Berücksichtigung von Farb- oder Textformatierungen git diff:

Keine der anderen Antworten hier (einschließlich meiner anderen Antwort ) wird genau das tun, was Sie zu 100% wollen. Diese Antwort wird jedoch. Hier ist ein 1-Liner, den Sie kopieren und in Ihr Terminal einfügen können. Ich habe es aus Gründen der Lesbarkeit nur aus mehreren Zeilen gemacht - Sie können es auf die gleiche Weise kopieren und einfügen, damit ich es genauso gut lesbar machen kann! Es basiert auf der awkProgrammiersprache:

git diff --color=always "$@" | awk '
# 1. Match and then skip "--- a/" and "+++ b/" lines
/^(\033\[(([0-9]{1,2};?){1,10})m)?(--- a\/|\+\+\+ b\/)/ {
    next 
} 
# 2. Now print the remaining "+" and "-" lines ONLY! Note: doing step 1 above first was required or
# else those lines would have been matched by this matcher below too since they also begin with 
# the "+" and "-" symbols.
/^(\033\[(([0-9]{1,2};?){1,10})m)?[-+]/ {
    print $0 
}
' | less -RFX

Hier sind seine Funktionen. Alle diese Merkmale lösen zusammen die Mängel jeder anderen Antwort hier:

  1. Es verarbeitet Farbe UND keine Farbausgabe. Das macht dieser reguläre Ausdruck:^(\033\[(([0-9]{1,2};?){1,10})m)?
  2. Es verarbeitet ALLE FARBEN und ALLE TEXTFORMATIERUNGSOPTIONEN, einschließlich Fett, Kursiv, Durchgestrichen usw., die Sie in Ihren git configEinstellungen festlegen können . Deshalb ist der regex oben hat ;?und {1,10}darin: wenn es den Beginn einer Farbe oder Textformatierung Code erkennt, wird es bis zu 10 Sequenzen dieses kombinierten ANSI - Codes entspricht.
  3. Es enthält NICHT auch Zeilen, die mit @@und dem Wort beginnen diff, wie es die akzeptierte Antwort tut. Wenn Sie diese Zeilen wollen (was ich ehrlich gesagt für nützlich halte :)), tun Sie stattdessen Folgendes:

    git diff --unified=0
    

    oder

    git diff -U0
    
  4. Es zeigt die Ausgabe genauso an wie git diffim lessPager mit optionaler Farbausgabe ( -R) und nur, wenn der Text> 1 Seite ( -F) ist und während Sie die aktuelle Textseite auf dem Bildschirm beibehalten, wenn Sie quit ( -X) .

Es hat auch den Vorteil, dass es leistungsstark und einfach zu konfigurieren ist, da es die Programmiersprache awk verwendet.

Wenn Sie awk lernen möchten , finden Sie hier einige Ressourcen:

  1. gawk(GNU awk) Handbuch: https://www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents
  2. Studie git diffnund die darin enthaltenen Kommentare: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/useful_scripts/git-diffn.sh
    1. Wenn Sie auch möchten git diffn, was git diffmit Zeilennummern ist, sehen Sie hier: Git Diff mit Zeilennummern (Git-Protokoll mit Zeilennummern)
  3. Einige Beispiele für awk "Hallo Welt" - und Syntaxtests: https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/tree/master/awk

Als Bonus habe ich auch das Obige eingepackt, um es als zu verwenden git diffc, was bedeutet "git diff, um NUR 'c'hanges zu zeigen". Verwendung ist identisch mit git diff; benutze git diffcstattdessen einfach ! Es unterstützt ALLE Optionen. Die Farbe ist standardmäßig eingeschaltet. Zum Ausschalten verwenden Sie einfach git diffc --no-coloroder git diffc --color=never. Siehe man git difffür Details.

Da ich gestern Abend gerade fertig war git diffn(ein Tool zum git diffAnzeigen mit Zeilen und Zahlen), war das Schreiben git diffctrivial. Ich dachte, ich mache es jetzt besser, während das Wissen in meinem Kopf frisch ist.

Installieren git diffc:

Befolgen Sie die Anweisungen am Ende dieser Antwort hier , außer überall, wo Sie git-diffnin den Anweisungen sehen, verwenden Sie git-diffcstattdessen. Das schließt auch den wgetBefehl ein. Das Herunterladen und Installieren git diffcist einfach: Es sind nur ein paar Befehle.

Gabriel Staples
quelle
0

Hier ist eine andere, einfachere Möglichkeit, nur Linien zu finden, die geändert wurden, und daher mit einem einzelnen +oder zu beginnen -, während die Farbausgabe beibehalten wird:

git diff -U0 --color=always HEAD~ | grep --color=never -E $'^\e\[(32m\+|31m-)'
  1. Das -U0sagt, dass 0 Kontextzeilen um die geänderten Zeilen eingeschlossen werden sollen - dh: nur die geänderten Zeilen selbst einschließen. Siehe man git diff.
  2. Mit -Efor grep kann mit erweiterten regulären Ausdrücken gearbeitet werden
  3. Die $''Syntax erlaubt anscheinend ANSI-Anführungszeichen, wodurch das ESC-Zeichen (Escape oder 0x1b) richtig interpretiert wird. Siehe hier .
  4. Und hier ist die Regex-Beschreibung von https://www.regex101.com :Geben Sie hier die Bildbeschreibung ein
  5. Entspricht im Wesentlichen ^dem Zeilenanfang, \estimmt mit dem Escape-Zeichen überein, das der Beginn eines Farbcodes im Terminal ist, \[stimmt mit dem nächsten Zeichen im Farbcode überein [, und dann (this|that)stimmt die Syntax mit "dies" oder "das" überein. , wobei "dies" ist 32m+, was eine grüne + Linie und 31m-eine rote Linie ist.
  6. Farben sind wie \e[32mfolgt : ist grün und \e[31mist rot.
  7. +zeigt git diffnatürlich Zeilen an, die als hinzugefügt markiert sind , und -zeigt Zeilen, die git diffals gelöscht markiert sind .
  8. Beachten Sie, dass dies im zweiten Ausdruck erforderlich--color=never ist ,grep um zu verhindern, dass Übereinstimmungen hervorgehoben werden, da sonst git diffdie von links eingehenden Farbcodes durcheinander geraten.
  9. Das +muss ebenfalls maskiert werden, \+da es sich ansonsten +um ein spezielles reguläres Ausdruckszeichen (Regex) handelt, das ein oder mehrere Vorkommen des vorhergehenden Elements angibt . Siehe hier: https://en.wikipedia.org/wiki/Regular_expression#Basic_concepts .

Verweise:

  1. https://git-scm.com/docs/git-diff#_combined_diff_format
  2. Antwort von @ user650654: Git diff zeigt nur Zeilen an, die geändert wurden
  3. Antwort von @wisbucky: Git diff zeigt nur Zeilen an, die geändert wurden

Verbunden:

  1. [meine eigene Antwort] Git Diff mit Zeilennummern (Git Log mit Zeilennummern)
  2. [Antwort eines anderen] Git diff mit Zeilennummern (Git-Protokoll mit Zeilennummern)
  3. Git Diff mit Zeilennummern und korrekter Code-Ausrichtung / Einrückung
  4. git-filechange-search.sh- Ein Skript, mit dem Sie eine Datei nach einem Variablen- oder Funktionsnamen durchsuchen und herausfinden können, welche Commits Änderungen an diesem Variablen- oder Funktionsnamen enthalten. Ex. Verwendung: Hier ./git-filechange-search.sh path/to/my/file.cpp variable_namefinden Sie alle Commits mit Änderungen an file.cpp, die darin enthalten variable_namesind. Dies ist nützlich, um zu sehen, wo und wann bestimmte Funktionen geändert wurden. Es ist, als wäre es eine Suche, die Abschnitte einer Datei beobachten könnte, die im git blameLaufe der Zeit angezeigt werden .
Gabriel Staples
quelle