7

I often need to search for a particular string from a directory that has git directory .git/. This is the command I use:

find . -name .git -prune -o -print | xargs grep <string-to-search>

The -name .git -prune -o -print option is to ignore the files under .git/. However, it outputs a lot of 'Is a directory' messages that clutter the whole result. For example,

...
grep: ./reports: Is a directory
grep: ./scripts: Is a directory
grep: ./scripts/js: Is a directory
grep: ./scripts/js/adapter: Is a directory
...

How to modify the command line so that I can ignore the .git/ directory and all other directories (i.e. only search the searchable files).

Apparently, the -type f option doesn't work well in:

find -type f . -name .git -prune -o -print
moey
  • 10,587
  • 25
  • 68
  • 112
  • 4
    Why aren't you using [`git-grep`](http://www.kernel.org/pub/software/scm/git/docs/git-grep.html)? – johnsyweb Jan 01 '13 at 10:03
  • 1
    Also, that last command should be `find . -type f -name .git -prune -o -print`. – johnsyweb Jan 01 '13 at 10:05
  • Thanks, @Johnsyweb. `find . -type f -name .git -prune -o -print` actually still outputs directories. – moey Jan 01 '13 at 10:13
  • 2
    You're right -- it's so much simpler using `git-grep`: `git grep --untracked `. Let me keep this question open; I am still curious how we'd do this using the combination of _grep_ and _find_. – moey Jan 01 '13 at 10:24
  • What if you have multiple .git cloned from various places (example using [repo](https://source.android.com/source/downloading.html)), can `git-grep` (or some other tool) handle this? – OLL Mar 21 '17 at 11:23

4 Answers4

25

You don't require find command. You can use grep to search in directory. You can ignore directory by using exclude-dir syntax.

grep -r --exclude-dir=".git;.svn" "string to search" <directory>
Vivek Goel
  • 22,942
  • 29
  • 114
  • 186
  • 3
    N.B: This requires [GNU Grep (>= 2.5.2)](http://stackoverflow.com/a/8692318/78845). – johnsyweb Jan 01 '13 at 10:02
  • 1
    Any alternative for a `grep (BSD grep) 2.5.1-FreeBSD`? Thanks! – moey Jan 01 '13 at 10:11
  • find . -not -iwholename '*.git*' – Vivek Goel Jan 01 '13 at 10:18
  • add an intermediate "anit-grep" to the pipeline, i.e. `grep -r ... | egrep -v '\.svn|\.git' | .....` Good luck to all. – shellter Jan 01 '13 at 23:12
  • 2
    This did not work for me with ; delimited paths. Try a single directory if you have any problems – Miquel Aug 22 '15 at 09:00
  • 3
    Upvoted because this works well with multiple .git repositories when using [repo](https://source.android.com/source/downloading.html). However, I had to split the `;` file delimiter like so: `grep -R --exclude-dir=".git" --exclude-dir=".svn" MyRegex` – OLL Mar 21 '17 at 11:28
4

Answering my own question here (without giving any votes, etc.):

Since I was essentially doing a search specifically in a git-tracked directory, git grep is apparently much simpler and more apt tool for the job. Thanks to @Johnsyweb who initially brought this up!

I chose Vivek's answer because it provides a general grep solution as asked in the original question.

moey
  • 10,587
  • 25
  • 68
  • 112
0

Recommend you try ripgrep https://github.com/BurntSushi/ripgrep

ripgrep is a line-oriented search tool that recursively searches the current directory for a regex pattern. By default, ripgrep will respect gitignore rules and automatically skip hidden files/directories and binary files.

It's faster and more developer friendly then other tools out there (that I've encountered) including grep and find

DBCerigo
  • 565
  • 6
  • 19
-1

The -type f is misplaced. It is filtering out directories before the -prune, which expects a directory name. The command should be find . -name .git -prune -o -type f -print. If you just want grep to shut up about directories, you can set the environment variable GREP_OPTIONS='--directories=skip'

dmearns
  • 31
  • 3