Reputation: 7515
I love git grep
to search in all files checked in to a repository. It's great. But is it possible to use it (or some other Git command) to just use to find files (independent of content)?
At the moment I do this:
find . | grep middleware
which works, but it's not using the Git index which means it's going through every found file and it reports on files that are matching the .gitignore
.
Are there some clever tricks?
Upvotes: 37
Views: 50695
Reputation: 5346
I have the same problem regularily, and I just went and hacked git find
– if you don’t use the Debian package you can just copy the git-find
script to /usr/lib/git-core/
(or comparable) and enjoy it.
It can be used in several modes, the easiest of which is indeed:
git find \*middleware\* # or
git find '*middleware*' # which is short for
git find -name '*middleware*'
Combining is also possible (and almost as flexible as regular find
, you just have to write the -a
explicitly):
git find \( -name \*.java -o -name \*.js \) -a ! -ipath \*/test/\*
It has a couple more options, most of which handle with filtering the name or full (partial, i.e. below the current working directory) path, some of them case-insensitively (-iname
and friends), and two global options, one to toggle regexp between POSIX Basic (default) and POSIX Extended, the other toggles symlinks (default on); this finds only files (and symlinks), not directories or submodules (“gitlinks”) by design.
It can also pass the file list to regular find(1) if it’s not too long (it must be passed on the command line), which allows for things like…
git find -- -mtime -100
… at slight filesystem cost (find
does access the filesystem), but on the other hand, almost all (not search depth-specific stuff) of find
works, and you only get to operate on files “in the index”, i.e. known to git (present in the HEAD commit or git add
ed).
It’s a bit picky about unresolved conflicts though. If you notice any problems with it, just drop me a note (here, or via IRC).
PS: Feel free to lobby the official git people to subtree-merge the git-find repository, I’d be more than happy to have it integrated into git proper (the licence is even more liberal, you just need the mksh
shell in a somewhat recent (50 should be sufficient) version, but it’s the most widespread Unix shell nowadays so that’s okay).
Upvotes: 0
Reputation: 11998
git grep
has built-in support to limit the grep to a glob of files. The other answers all use external tools to do the actual grepping, which misses the point.
Example from the git grep
man page.
git grep 'time_t' -- '*.[ch]'
Looks for time_t in all tracked .c and .h files in the working directory and its subdirectories.
From the option descriptions.
--
Signals the end of options; the rest of the parameters are limiters.
<pathspec>…
If given, limit the search to paths matching at least one pattern. Both leading paths match and glob(7) patterns are supported.
So to translate your example (which did not include something to limit the search however so I added it here):
find . -name '*.txt' | grep middleware
You would do:
git grep middleware -- '*.txt'
Upvotes: 2
Reputation: 10385
You might consider a non-Git solution in this case.
find
itself has the ability to do what you want in a more efficient manner than piping its results into grep
:
find . -name 'middleware*'
You will need to quote the pattern so that the *
isn't expanded by the shell before being passed to find
.
There is a powerful program called ack
that is, well, better than grep, and one of my favorite uses for ack
is exactly what you've mentioned—finding files that match a pattern within a tree. ack
uses Perl regular expressions (PCRE), not shell fileglobs, though.
ack -g middleware
If you want to search within those files, ack
lets you do that more easily than writing a shell loop over the results of find
that grep
s within each file. Compare the two and see which one you prefer:
for f in $(find . -name 'middleware*')
do
grep 'pattern in file' $f
done
versus
ack -G 'middleware' 'pattern in file'
I highly recommend ack
as something to add to your toolkit.
Upvotes: 6
Reputation: 2275
I think git ls-files
will do the trick for you.
So:
git ls-files "*middleware*"
Upvotes: 27
Reputation: 11
Git now has a matured search functionality (as the previous poster mentioned). You can search file names, extensions, by programming language, etc. You can search inside at file contents, etc.
You search when you log into GitHub, at the search field in the upper left of the screen.
See this for details: Searching code (legacy)
Upvotes: 1
Reputation: 133792
You may want git ls-files
which lists the files in the index (and automatically adjusts for your current directory inside the Git work directory).
Upvotes: 50