web-dev-qa-db-fra.com

Comment grep des fichiers dans git repo?

J'aime git grep pour rechercher dans tous les fichiers archivés dans un dépôt. C'est bien. Mais est-il possible de l’utiliser (ou d’autres commandes git) pour rechercher des fichiers (indépendamment du contenu)?

Au moment où je fais ceci:

$ find . | grep middleware

ce qui fonctionne mais n'utilise pas l'index git, ce qui signifie qu'il parcourt tous les fichiers trouvés et qu'il enregistre les fichiers correspondant au .gitignore.

Des idées pour des astuces intelligentes?

28
Peter Bengtsson

Vous voulez peut-être git ls-files qui répertorie les fichiers de l'index? (et s'adapte automatiquement à votre répertoire actuel dans le répertoire de travail git)

39
araqnid

Je pense que git ls-files fera l'affaire pour vous.

Alors:

 git ls-files "*middleware*"
20
Steven

Vous pourriez envisager une solution non-git dans ce cas.

find lui-même a la capacité de faire ce que vous voulez de manière plus efficace que de transférer ses résultats dans grep:

find . -name 'middleware*'

Avant de passer à find, vous devrez citer le motif de sorte que le * ne soit pas développé par le shell.

Il existe un programme puissant appelé ack qui correspond bien à meilleur que grep , et l’une de mes utilisations préférées de ack est exactement ce que vous avez mentionné - trouver des fichiers qui correspondent à un motif dans une arborescence . ack utilise les expressions rationnelles Perl, et non pas les fichiers de fichiers shell.

ack -g middleware

Si vous souhaitez rechercher dans ces fichiers, ack vous permet de le faire plus facilement que d'écrire une boucle Shell sur les résultats de find que greps dans chaque fichier. Comparez les deux et voyez lequel vous préférez:

for f in $(find . -name 'middleware*')
do
    grep 'pattern in file' $f
done

versus

ack -G 'middleware' 'pattern in file'

Je recommande fortement ack à ajouter à votre boîte à outils.

4
MikeSep

J’ai régulièrement le même problème, et je viens de pirater git find - si vous n’utilisez pas le paquet Debian vous pouvez simplement copier le script git-find dans /usr/lib/git-core/ (ou comparable) et l’apprécier.

Il peut être utilisé dans plusieurs modes, le plus simple étant:

git find \*middleware\*        # or
git find '*middleware*'        # which is short for
git find -name '*middleware*'

La combinaison est également possible (et presque aussi flexible que la variable find régulière, il vous suffit d'écrire explicitement le -a):

git find \( -name \*.Java -o -name \*.js \) -a ! -ipath \*/test/\*

Il a quelques autres options, dont la plupart traitent avec le filtrage du nom ou du chemin complet (partiel, c'est-à-dire sous le répertoire de travail en cours), certaines sans distinction de casse (-iname et amis), et deux options globales, l'une pour basculer les expressions rationnelles. entre POSIX Basic (valeur par défaut) et POSIX Etendue, l’autre bascule les liens symboliques (valeur par défaut); cela ne trouve que des fichiers (et des liens symboliques), et non des répertoires ou des sous-modules («gitlinks») par conception.

Il peut également transmettre la liste de fichiers à find (1) si elle n’est pas trop longue (elle doit être passée sur la ligne de commande), ce qui permet des choses comme…

git find -- -mtime -100

… À un faible coût pour le système de fichiers (find accède au système de fichiers), mais par contre, la quasi-totalité (et non les recherches liées à la profondeur) de find fonctionne et vous ne pouvez utiliser que des fichiers «dans l'index», c'est-à-dire git (présent dans le commit HEAD ou git added).

C’est cependant un peu difficile en ce qui concerne les conflits non résolus. Si vous remarquez des problèmes, envoyez-moi simplement une note (ici ou via IRC).

PS: N'hésitez pas à faire pression sur le peuple git officiel pour qu'il sous-fusionne le référentiel git-find, je serais plus qu'heureux de l'intégrer à git lui-même (la licence est encore plus libérale, vous avez simplement besoin de la mksh Shell dans un une version un peu récente (50 devrait suffire), mais c'est le shell Unix le plus répandu de nos jours, donc ça va).

0
mirabilos