web-dev-qa-db-fra.com

Comment grep le git diff?

Est-il possible d'afficher le git-diff filtré par un motif donné?.

Quelque chose comme 

git grepdiff pattern

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

Malheureusement, la solution la plus simple ne suffit pas

git diff | grep pattern 

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

Je suis venu avec une solution de contournement en utilisant awk

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

Mais j'aimerais savoir qu'il existe une commande pour cela.

51
Kuba

Pas sûr, mais git diff -G <regex> n'est-il pas correct?

-G <regex>

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

Une autre possibilité consisterait à afficher l'intégralité du fichier diff et à rechercher le résultat à l'aide des commandes less normales (tapez /, puis le modèle).

Lorsque vous avez configuré less pour afficher certaines lignes avant la correspondance à l'aide de --jump-target=N, ceci est très utile. Essayez comme ça:

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

Cela signifie que la correspondance doit apparaître sur la ligne 10 (affiche 9 lignes de contexte ci-dessus), ce qui peut être suffisant pour afficher également le nom du fichier.

Vous pouvez également utiliser par exemple --jump-target=.5 pour le faire positionner la correspondance au milieu de l'écran.

9
robinst

Avez-vous essayé git diff -S<string> ou git diff -G".*string.*"? Notez qu'ils ne sont pas équivalents, voir la documentation sur pioche pour ce que fait -S.

8
robinst

J'utilise git log -p, qui ouvre moins (configurable, cependant), qui peut à son tour être recherché avec /. Il y a aussi git log -S <searchword>.

3
chelmertz

Je pense que votre approche de "grep" diff est la meilleure solution de contournement.

Vous pouvez améliorer votre script awk en utilisant sed:

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 pour correspondre aux lignes de couleur du terminal
  • marker: marqueur pour faire correspondre la division de _diff mecs, lignes commençant par "diff" coloré
  • pattern: motif à rechercher, lignes commençant par "+" ou "-" et contenant "PATTERN"

Ceci imprimera des morceaux de diff complets, avec PATTERN ajouté ou supprimé, tout en maintenant une sortie couleur utile.

Notez que ^[ dans colored doit être réel, littéral ^[. Vous pouvez les saisir en bash en appuyant sur Ctrl + VCtrl + [

1
Hazzard17

Sous Windows, une solution simple consiste à:

git diff -U0 | findstr string

Si vous voulez grouper par nom de fichier, utilisez ceci

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

Cela a fait le travail pour moi, j'espère que cela aidera quelqu'un:

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

Voici un outil de différenciation personnalisé qui permet de mettre à l’intérieur des modifications (mais pas le contexte):

Utilisation

GIT_EXTERNAL_DIFF="mydiff --grep foo" git diff

Cela générera dans vos modifications les lignes contenant foo (y compris les lignes où foo a disparu à cause de vos modifications). Tout modèle grep peut être utilisé à la place de foo.

Chaque ligne de sortie commence par le préfixe suivant:

filename: oldlinenum: newlinenum|

Le script peut également être utilisé sans l'option --grep, auquel cas il formate simplement le diff complet (c'est-à-dire fournissant un contexte complet) comme décrit ci-dessus.

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
Leon