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?

  • 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 Apr 5 '14 at 3:47
6

Sounds like you want the -maxdepth option.

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

  • 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 Apr 2 '14 at 2:11
2

Find all directories which contain a .git subdirectory:

find /home/code -type d -name .git -exec dirname {} \;
  • Hmm. 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 Apr 3 '14 at 1:36
  • @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 Apr 3 '14 at 6:47
  • 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 Apr 3 '14 at 14:38
  • 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 Apr 3 '14 at 15:02
1

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.

  • 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 Apr 2 '14 at 2:11
  • In this case the answer is provided by UnlimitedInfinity above... – Paxsali Apr 2 '14 at 11:56

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.