How to exclude certain directories/files from git grep search

Solution 1:

In git 1.9.0 the "magic word" exclude was added to pathspecs. So if you want to search for foobar in every file except for those matching *.java you can do:

git grep foobar -- ':(exclude)*.java'

Or using the ! "short form" for exclude:

git grep foobar -- ':!*.java'

Note that in git versions up to v2.12, when using an exclude pathspec, you must have at least one "inclusive" pathspec. In the above examples you'd want to add ./* (recursively include everything under the current directory) somewhere after the -- as well. In git v2.13 this restriction was lifted and git grep foobar -- ':!*.java' works without the ./*.

There's a good reference for all the "magic words" allowed in a pathspec at git-scm.com (or just git help glossary).

Solution 2:

Update: For git >= 1.9 there is native support for exclude patterns, see onlyone's answer.

This may seem backwards, but you can pass a list of files not matching your exclude pattern to git grep like this:

git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>`

grep -v returns every path not matching <exclude-pattern>. Note that git ls-files also takes a --exclude parameter, but that is only applied to untracked files.

Solution 3:

It's not possible, but has been discussed recently. Proposed workaround in link:

You can put *.dll to .gitignore file then git grep --exclude-standard.

EDIT see onlynone's answer, since git 1.9.0 it's possible.

Solution 4:

You can mark files or directories as binary by creating an attributes file in your repository, e.g.

$ cat .git/info/attributes 
directory/to/ignore/*.* binary
directory/to/ignore/*/*.* binary
another_directory/to/also/ignore/*.* binary

Matches in binary files are listed without the including line, e.g.

$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename:      foo << bar - bazz[:whatnot]