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?
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)
Je pense que git ls-files
fera l'affaire pour vous.
Alors:
git ls-files "*middleware*"
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 grep
s 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.
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 add
ed).
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).