Question: I can't figure out how the find -not works.

Let's say that I would like to locate all .git dirs in the tree.

```
find -type d -iname .git

```

No problems, but then let's say that I have some dirs that I don't like to be included, in question they can be called "old" and "backup".

I could pipe to grep -v and that will work just fine.

```
find -type d -iname .git | grep -v old | grep -v backup

```

But when I browsed the man page for find I noticed that there is a -not, but I can't figure out how it is intended to work.

I tried like this, but he does not exclude the old dir.

```
find -type d -iname .git -not -iname old 

```

How does the find -not work? Can I use it for this find of problem?

Answer: 
You need the `-prune` option of `find`,
it's really pretty tricky. It requires to use `-path` instead of `-name` too.

I think you want to use this:

```
find . -type d \( -path '*/old' -prune -o -iname '.git' -print \)

```

The effect of the `-not` is implemented by 

* matching old "old", and the donig nothing
* or (using option -o)
* matching ".git" and printing the name
* or (by default)
* doing nothing (because the normal default action of find, an implicit `-print` at the end of the command line, is disabled, if `-print` is used already)

I recognize that other variants, while *looking* more complicated on the command line, may be easier to use, for example because the use of a different logic expression, and the changing of the default action.  

On the other hand, the variants involving `-prune` are easier to generalize for more complex cases, when other syntax will be hard to handle just because it gets too long to read.
> 
> 
> ```
> find -type d -iname .git -not -iname old 
> 
> ```
> 
> 

This matches directories which are called `.git` and not called `old`. Since a directory which is called `.git` cannot be called `old`, the `-not -iname old` part can be removed without changing the meaning of the command.

`-not` says “don't match”, but not “don't recurse into”. There's a different way to say “don't recurse into”: it's an action called `-prune`. The following command means “traverse all directories recursively (`find`), but stop at directories called `old` (`-iname old -prune`), and print directories called `.git`”:

```
find -iname old -prune -o -type d -iname .git -print

```

This is parsed as `( -iname old -prune ) -o ( -type d -iname .git -print )`. Find is told to look for files that meet the conditions `-iname old` or (`-o`) `-type d -iname .git`. When a file meets the first condition, the action `-prune` (prune from the traversed tree, i.e. don't recurse) is executed. When a file meets the second condition, the action `-print` is executed. As printing is the default action, you can omit `-print`.