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? – Michael Homer Jan 12 '16 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. – Ashhar Hasan Jan 12 '16 at 7:09
  • The main hurdle I'm facing is how to restrict the search to only top level git repos. – Ashhar Hasan Jan 12 '16 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. – Michael Homer Jan 12 '16 at 7:14

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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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