I have a folder full of source files for an application, the project uses git for version control and so there is a .git directory: composer.json .git  branches  config  info  logs  objects  packed-refs  refs .gitignore Gruntfile.js less  framework  index.less  view_specific.less package.json[...]I regularly need to do something with all the source files whilst ignoring  the version control files, i.e. the .git directory and everything under it.I normally use the -not -path option to find to exclude a directory, e.g.find . -not -path *git* the problem with this is that it is too broad, e.g. it will exclude the .gitignore file, and any other files that have git in them, e.g. agitate, fugitive etc.I discovered find with the -name and -prune switch does seem to target the .git directory and its contents:% find . -name .git -prune -o -print | grep git./.gitignorebut I don't understand  how -name is matching the filenames.From man find   -name pattern      Base  of  file  name (the path with the leading directories removed) matches shell pattern pattern.  To me this implies, -name only matches when the pattern matches the last segment in a filename, e.g. -name foo would match /dir1/dir2/foo but not /dir1/dir2/foo/dir3/dir4/some_fileto me the whole point of -path was for matching patterns like foo to files with pathnames like /dir1/dir2/foo/dir3/dir4/some_file.It seems -name can match any segment in the filepath - not just the last segment - as long as its a complete match to the segment within the slashes?Otherwise how does -name match file names?
How does the -name switch to GNU find work when targeting a directory and its contents?
find
To ignore the .git directories and everything underneath them you need a construct like thisfind . \( -name '.git' -prune \) -o \( -print {or whatever else you want to do} \)This tells find that when it finds a file or directory called .git it's to prune its tree and not descend any further down that path. Everything else can be matched - and processed - within the other half of the or condition construct.(The backslashes on the brackets stop them being processed by the shell, and for this simplistic example are technically un-necessary. I've left them in to make it explicitly obvious how the and and or constructs bind.)Now, consider your concern with a folder called foo:e.g. -name foo would match /dir1/dir2/foo but not /dir1/dir2/foo/dir3/dir4/some_fileYou are correct, but I think you've missed the corollary. At some point find will reach /dir1/dir2/foo. The -name foo will match and so the -prune will be invoked. find cannot reach below foo without first seeing foo itself.Consequently /dir1/dir2/foo/dir3/dir4/some_file can never be reached.The initial result from inspection is that somehow -name foo matches /dir1/dir2/foo/dir3/dir4/some_file, but in reality it matched on /dir1/dir2/foo and abandoned any further inspection of that tree.In contrast to -name foo, which matches foo only as the last component of a path, -path foo will match only if foo is a complete path. (find * -path foo might match a foo at the top level, but find . -path foo could never match ./foo.)