Dans un référentiel git, existe-t-il une différence/avantage utilisant git grep
par rapport au bon vieux grep
?
Un exemple serait?
Les deux sont très similaires. La principale différence est que git grep
utilise par défaut la recherche dans les fichiers suivis par git.
Si je veux trouver foo
dans mon projet, je peux utiliser git grep
ou bon vieux autonome grep
:
git grep foo
grep -R foo .
La version git grep
ne cherchera que dans les fichiers suivis par git, alors que la version grep
cherchera dans tout le répertoire. Jusqu'ici si semblable. l'un ou l'autre pourrait être mieux dépendant de ce que vous voulez réaliser.
Que faire si nous voulons limiter la recherche à uniquement les fichiers .rb
?
git grep foo -- *.rb
grep -R --include=*.rb foo .
La vieille version grep
devient un peu plus verbeuse, mais si vous êtes habitué à utiliser grep
, cela ne posera peut-être pas un problème. Ils ne vont toujours pas rechercher exactement les mêmes fichiers, mais encore une fois, cela dépend de ce que vous voulez réaliser.
Qu'en est-il de la recherche dans la version précédente du projet?
git grep foo HEAD^
git checkout HEAD^; grep -R foo .; git checkout -
C'est ici que git grep
fait une réelle différence: vous pouvez effectuer une recherche dans une autre révision du projet sans l'avoir extrait au préalable. Ce n'est pas une situation qui arrive trop souvent pour moi cependant; J'ai l'habitude de chercher dans la version du projet que j'ai extrait.
Certaines variables git config
modifient le comportement de git grep
et évitent de devoir passer deux arguments en ligne de commande:
grep.lineNumber
: affichez toujours les numéros de ligne des correspondances (vous pouvez passer -n
à la fois grep
et git grep
pour obtenir ce comportement)grep.extendedRegexp
: utilisez toujours des expressions régulières étendues (vous pouvez transmettre -E
à grep
et git grep
pour obtenir ce comportement)En pratique, gg
est associé à git grep -En
et cela fait presque toujours ce que je veux.
Le principal avantage de git grep
est qu’il peut trouver les modèles dans le référentiel git, i. e. également dans d'autres que la version actuelle de la source. Cela ne peut pas être fait en utilisant la variable standard grep
bien sûr. De plus, il y a beaucoup plus de fonctionnalités dans git grep
telles que l'arithmétique des motifs (des choses comme git grep -e pattern1 --and --not \( -e pattern2 -e pattern3 \)
), la recherche dans l'arborescence à l'aide de glob (des choses comme git grep pattern -- '*.[ch]'
pour rechercher uniquement dans les fichiers .c
et .h
) et quelques autres.
Voici un exemple de session pour rechercher dans une révision plus ancienne:
$ mkdir git-test # create fresh repository
$ cd git-test/
$ git init .
Initialized empty Git repository in /home/alfe/git-test/.git/
$ echo eins zwei drei > bla # create example file
$ git add bla # add and commit it
$ git commit bla
[master (root-commit) 7494515] .
1 file changed, 1 insertion(+)
create mode 100644 bla
$ echo vier fuenf sechs > bla # perform a change on that file
$ git commit -m 'increase' bla # commit it
[master 062488e] increase
1 file changed, 1 insertion(+), 1 deletion(-)
$ git grep eins | cat # grep for outdated pattern in current version
# (finds nothing)
$ git grep eins master^ | cat # grep for outdated pattern on former version
# finds it:
master^:bla:eins zwei drei
Si vous recherchez des modèles/chaînes dans un référentiel git (c'est-à-dire dans des fichiers déjà suivis), alors oui, git grep devrait être beaucoup plus rapide, en général, que grep normal, car il est indexé. (Vous pouvez essayer cela manuellement, le git-grep devrait être sensiblement plus rapide)
git grep
recherche uniquement dans les fichiers suivis dans le référentiel.
Avec grep
, vous devez passer la liste des fichiers dans lesquels vous souhaitez effectuer la recherche et vous devez filtrer vous-même tous les fichiers non suivis.
Donc, si vous recherchez quelque chose que vous savez se trouver dans le dépôt, git grep
vous fait gagner du temps car tout ce que vous avez à faire est de fournir le modèle. C'est également utile pour ne pas avoir à chercher dans tout ce qui n'est pas suivi dans le repo.
Si vous recherchez dans un dépôt Git, git grep
est plus rapide.
Et avec Git 2.20 (T4 2018), il est également plus compatible, en ce qui concerne les options, avec la variable grep
.
Comme indiqué dans ce git grep
"liste de souhaits" :
J'utilise souvent "
grep -r $pattern
" pour récursivement grep un arbre source.
Si cela prend trop de temps, je tape^C
et marque "git
" devant la ligne de commande, puis je le relance.
Git se plaint alors que "error: unknown switch
r '" because "
git grep`" est naturellement récursif.Pourrions-nous avoir "
git grep -r
" accepter l'argument de compatibilité?
D'autres commutateurs importants de grep, tels que "-i
", sont compatibles. L'ajout de-r
améliorerait la convivialité.
Ceci est maintenant (Git 2.20, Q4 2018) fait:
Voir commit 0a09e5e (01 oct 2018) de René Scharfe (rscharfe
) .
Proposé par: Junio C Hamano (gitster
) .
(Fusion par Junio C Hamano - gitster
- in commit 9822b8f , 19 octobre 2018)
grep
: ajouter-r/--[no-]recursive
Reconnaître
-r
et--recursive
comme synonymes de--max-depth=-1
pour des raisons de compatibilité avec GNU grep; c'est toujours la valeur par défaut pourgit grep
.Cela ajoute également
--no-recursive
comme synonyme de--max-depth=0
gratuitement, , Ce qui est bienvenu pour des raisons d’intégralité et de cohérence.Corrigez la description de
--max-depth
alors que nous y sommes. Les valeurs négatives autres que -1 désactivent la récursivité, c’est-à-dire qu’elles équivalent à--max-depth=0
.