Wie grep ich den Git Diff?


81

Gibt es eine Möglichkeit, das nach einem bestimmten Muster gefilterte Git-Diff anzuzeigen?

Etwas wie

git grepdiff pattern

changed file
+++ some sentence with pattern
changed file 2
--- some other pattern

Leider ist die einfachste Lösung nicht gut genug

git diff | grep pattern 

+++ some sentence with pattern
--- some other pattern
# not an option as doesn't put the filename close to the match

Ich kam mit einer Problemumgehung mit awk

git diff | awk "/\+\+\+/{f = \$2}; /PATTERN/ {print f \$0} "

Würde aber gerne herausfinden, dass es dafür einen Befehl gibt.


3
Anscheinend macht das Github-Projekt git-diff-grep etwas völlig anderes.
— Kuba

Antworten:


98

Nicht sicher, aber nicht git diff -G <regex>Flagge OK?

-G <Regex>

Look for differences whose added or removed line matches the given <regex>.

15
Das ist nicht genau das, wonach ich suche, da ich nur die Linien sehen möchte, die mit dem Muster übereinstimmen - nicht den gesamten Unterschied einer Datei, die die Änderung mit dem Muster beinhaltet
— Kuba

dann gibt es wohl keine einfachere Lösung als deine
— CharlesB

Zumindest Git Diff-G ist ein besserer erster Schritt als das Full Git Diff.
— Kuba

1
Meine Version hat nicht das Flag -G. Wurde es entfernt?
— RedX

3
Auch nützlich, um zu sehen, welche Dateien von der Regex betroffen waren:git diff -G <regex> --raw
— Raman


11

Eine andere Möglichkeit wäre, das gesamte Diff anzuzeigen und die Ausgabe mit den normalen lessBefehlen (Typ /und dann das Muster) zu durchsuchen .

Wenn Sie so lesskonfiguriert haben, dass einige Zeilen vor dem Spiel angezeigt werden --jump-target=N, ist dies sehr nützlich. Versuchen Sie es so:

PAGER="/usr/bin/less --jump-target=10" git diff

Dies bedeutet, dass die Übereinstimmung in Zeile 10 angezeigt werden sollte (zeigt 9 Kontextzeilen oben), was möglicherweise ausreicht, um auch den Dateinamen anzuzeigen.

Sie können zB auch verwenden --jump-target=.5, um die Übereinstimmung in der Mitte des Bildschirms zu positionieren.


3

Ich benutze git log -p, was weniger öffnet (allerdings konfigurierbar), mit dem wiederum gesucht werden kann /. Es gibt auch git log -S <searchword>.


Ich kenne diese - indem ich nicht in die Geschichte schaue, sondern in die aktuellen Arbeitsveränderungen.
— Kuba

Okay, dann könnte die gleiche Methode (wie von robinst zitiert) verwendet werden. Wenn Sie die Ausgabe wünschen, können Sie wahrscheinlich eine beliebige Bibliothek mit libgit2 oder gitgui / gitk verwenden.
— Chelmertz

1

Das hat den Job für mich gemacht, ich hoffe es wird jemandem helfen:

git diff | grep  -P '^\+|^\-'

1

Ich denke, Ihr Ansatz zur "grep" diff-Ausgabe ist die beste Problemumgehung.

Sie können Ihr awk-Skript verbessern, indem Sie sed verwenden:

colored="(^[\[[0-9;]*[a-zA-Z])"
marker="^$colored+diff"
pattern="^$colored+.*(\+|\-).*PATTERN"
git diff --color | sed -rn -e "/$marker/! H; /$marker/ ba; $ ba; b; :a; x; /$pattern/ p"
  • colored: Regex passend zu den farbigen Linien des Terminals
  • marker: Marker zur Übereinstimmung mit der Teilung von verschiedenen diffHunks, Linien beginnend mit farbigem "diff"
  • pattern: zu suchendes Muster, Zeilen, die mit "+" oder "-" beginnen und "MUSTER" enthalten

Dadurch werden vollständige Diff-Hunks mit hinzugefügtem oder entferntem MUSTER gedruckt, wobei auch die nützliche Farbausgabe beibehalten wird.

Beachten Sie, dass ^[in coloredtatsächlich und wörtlich sein sollte ^[. Sie können sie in Bash eingeben, indem Sie Ctrl+ V, Ctrl+ drücken[


Ausgezeichnet!! für jeden , der versucht dies anderes als ein Bash - Shell in irgendwo eingeben (zB Bearbeitung .sh Datei in IDE) müssen Sie die ersetzen , ^[wie colored=$'(\e\[[0-9;]*[a-zA-Z])'und auf macOS Sie auch müssen brew install gnu-sedund ersetzensed --> gsed
— Anentropic

0

Hier ist ein benutzerdefiniertes Diff-Tool, mit dem Sie Änderungen (aber nicht den Kontext) erfassen können:

Verwendung

GIT_EXTERNAL_DIFF="mydiff --grep foo" git diff

Dadurch werden die Zeilen in Ihren Änderungen ausgegeben, die enthalten foo(einschließlich Zeilen, foodie aufgrund Ihrer Änderungen verschwunden sind). Stattdessen kann jedes grep-Muster verwendet werden foo.

Jede Ausgabezeile beginnt mit dem folgenden Präfix:

filename: oldlinenum: newlinenum|

Das Skript kann auch ohne die --grepOption verwendet werden. In diesem Fall formatiert es einfach das vollständige Diff (dh das Bereitstellen des vollständigen Kontexts) wie oben beschrieben.

mydiff

#!/bin/bash

my_diff()
{
    diff --old-line-format="$1"':%6dn:      |-%L'     \
         --new-line-format="$1"':      :%6dn|+%L'     \
         --unchanged-line-format="$1"':%6dn:%6dn| %L' \
         $2 $3
}

if [[ $1 == '--grep' ]]
then
    pattern="$2"
    shift 2
    my_diff "$1" "$2" "$5"|grep --color=never '^[^|]\+|[-+].\+'"$pattern"'.*'
else
    my_diff "$1" "$2" "$5"
fi

exit 0

0

Unter Windows ist eine einfache Lösung:

git diff -U0 | findstr string

Wenn Sie nach Dateinamen gruppieren möchten, verwenden Sie diese Option

FOR /F "usebackq delims==" %i IN (`git diff --name-only`) do git diff -U0 %~fi | findstr string

0

Ich habe dies mit großer Zufriedenheit benutzt :)

grep -ri <MY_PATTERN> $(git diff 790e26393d --name-only) 
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.