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.