Using Unix's find command to find directories matching name but not subdirectories with same name

7

Edited: I mistakenly misrepresented my problem. A more accurate example now appears below.

I'd like to recursively walk all directories inside a target directory, and stop each recursive call after the first .git directory is found.

For example, if we have these paths:

/home/code/twitter/.git/
/home/code/twitter/some_file
/home/code/twitter/some_other_file 
/home/code/facebook/.git/
/home/code/facebook/another_file
/home/code/configs/.git/
/home/code/configs/some_module/.git/
/home/code/configs/another_module/.git/
/home/code/some/unknown/depth/until/this/git/dir/.git/
/home/code/some/unknown/depth/until/this/git/dir/some_file

I want only these lines in the result:

/home/code/twitter
/home/code/facebook
/home/code/configs
/home/code/some/unknown/depth/until/this/git/dir/

The -maxdepth won't help me here because I don't know how deep the first .git dir will be for each subdirectory of my target.

I thought find /home/code -type d -name .git -prune would do it, but it's not working for me. What am I missing?

Gabe Hollombe

Posted 2014-04-01T12:06:47.927

Reputation: 171

It appears that this may not be possible... I'll leave this question open in case anyone else discovers this in the future and has an answer. – Gabe Hollombe – 2014-04-05T03:47:45.370

Answers

6

Sounds like you want the -maxdepth option.

find /home/code -maxdepth 2 -type d -name .git

Digital Chris

Posted 2014-04-01T12:06:47.927

Reputation: 408

A good thought, but it won't help me here. I've updated my example to more accurately reflect my problem, and I'm so sorry for not having it right the first time. – Gabe Hollombe – 2014-04-02T02:11:01.173

2

It's tricky and -maxdepth and recursion trickery won't help here, but here's what I would do:

find /home/code -type d -name ".git" | grep -v '\.git/'

In english: find me all directories named ".git" and filter out any occurences in the resultlist which contain ".git/" (dot git slash).

Above commandline will work on all unix systems, however, if you can assert that your find will be "GNU find", then this will also work:

find /home/code -type d -name ".git" ! -path "*/.git/*"

Have fun.

Paxsali

Posted 2014-04-01T12:06:47.927

Reputation: 134

This would totally work for the problem as it was originally asked by me. Alas, I totally didn't ask the right question for my situation. I've updated my example to more accurately reflect my problem, and I'm so sorry for not having it right the first time. Can you take a look again and share some experience? – Gabe Hollombe – 2014-04-02T02:11:56.633

In this case the answer is provided by UnlimitedInfinity above... – Paxsali – 2014-04-02T11:56:38.320

2

Find all directories which contain a .git subdirectory:

find /home/code -type d -name .git -exec dirname {} \;

UnlimitedInfinity

Posted 2014-04-01T12:06:47.927

Reputation: 293

1Hmm. This seems to give me back all dirs with a .git subdir. But I want it to stop at the first dir with a .git subdir for each branch of recursion. – Gabe Hollombe – 2014-04-03T01:36:15.920

@GabeHollombe you are assuming that this directory /home/code/twitter/.git/ will be found by find before these directories get found: /home/code/twitter/some_file /home/code/twitter/some_other_file. Why do you make that assumption? – UnlimitedInfinity – 2014-04-03T06:47:57.870

Yep. That's a fair point. I suppose it's more of a request, not an assumption, though. I know I can achieve what I want with some simple scripting, too. I just wondered if there was a simple-ish way to do it with one command. – Gabe Hollombe – 2014-04-03T14:38:16.177

1@GabeHollombe Actually it seems that find processes dot-dirs before non-dot-dirs; however, a directory could have several .dirs and in that case, the output would still be arbitrary. Yes, it looks like you will have to control recursion yourself in a script. I was thinking, maybe the output is more important to you than blocking the recursion, so I took a stab at the problem... – UnlimitedInfinity – 2014-04-03T15:02:43.613