I basically want to find all git repos that have neither a .gitattributes nor a .gitignore file at the root.

I used find . -type d '!' -exec test -e "{}/.gitignore" ';' -print to find it but it lists out all the directories instead of only the top level git directories.

My directory tree looks like this:

├─ _Clones
|  ├─ repo1 (has .gitignore)
|  └─ repo2
├─ _Forks
|  ├─ repo1 (has .gitattributes)
|  └─ _For-Later
|      ├─ repo2
|      └─ repo3
├─ myrepo1 (has both)
├─ myrepo2 (has both)
└─ myrepo10

In such a layout I would want the output to be _Clones\repo2, _Forks\_For-Later\repo2, _Forks\_For-Later\repo3 and myrepo10.

I've tried using depth parameter for find but that is a variable for each directory!

  • Both .gitignore and .gitattributes can appear anywhere within the repository; do you care about that? Jan 12, 2016 at 7:07
  • No. I actually want to see the repos I haven't configured properly. I learn about .gitattributes pretty recently so am looking to do a cleanup. For what you are saying, I already wrote that find command. Jan 12, 2016 at 7:09
  • The main hurdle I'm facing is how to restrict the search to only top level git repos. Jan 12, 2016 at 7:11
  • 1
    I've edited the first sentence - that seems to me to be what you want from the comment and the diagram, but check that it represents what you're looking for. Jan 12, 2016 at 7:14

1 Answer 1


To list the root directories of git repositories, I use the following:

find . -name .git -print0 | xargs -0 dirname

A variant finds all folders containing .gitignore:

find . -name .gitignore -print0 | xargs -0 dirname

Determining git repositories whose root doesn't contain .gitignore is then simply a set operation on the two sets of folders:

comm -23 <(find . -name .git -print0 | xargs -0 dirname | sort) <(find . -name .gitignore -print0 | xargs -0 dirname | sort)

This compares the two sets of folders (which have to be sorted) and lists those which only appear in the first set. The <() operation is process substitution and allows the output of any command to be used as input to another command instead of a file.

Replace .gitignore with .gitattributes above to find the git repositories which don't contain .gitattributes in their root directory...

To get the final output you're after, combine both:

comm -23 <(comm -23 <(find . -name .git -print0 | xargs -0 dirname | sort) <(find . -name .gitignore -print0 | xargs -0 dirname | sort)) <(find . -name .gitattributes -print0 | xargs -0 dirname | sort)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .