Credits to this SO answer this SO answer and this blog post for pieces of this answer.
Credits to this SO answer and this blog post for pieces of this answer.
Credits to this SO answer and this blog post for pieces of this answer.
This works based on the fact that all valid git repositories contain a directory titled .git
. The -execdir
flag to find
makes the given command run within the directory that contains the found file. So, what this command does is:
find . # find recursively, starting in the current directory...
-type d # ...files of type "directory"...
-name '.git' # ...whose name is '.git'...
-print # ...then, for each file found, print the name of the file (the dir) you found, and...
-execdir git status \; # ...from the directory containing that .git dir, run 'git status', and...
-exec echo \; # ...finally 'echo' to insert a blank line in the output for readability.
This is great for any git
commands you need to run. Unfortunately, because it depends on the presence of the .git
directory to establish which subdirs to run in, it's non trivial to extend it to run arbitrary commands.
In other words, it doesn't actually "run the command recursively in all subdirs until it finds one that works", as requested in the question post. Instead, it uses the presence of a specific file (in this case a .git
dir) to establish which subdirs to run in, and then runs the command only in those specific dirs.
I have never used hg
, but from a quick google search it appears that hg repos are similar to git repos and contain a .hg
directory in each valid repo. So this command could probably work for hg
commands also. Just replace .git
with .hg
and git status
with the hg command you want to run.
So if there is a single file or directory whose presence will guarantee you want to run the command (and that it will succeed) and whose absence will guarantee that you don't want to run the command (i.e. that the command will fail), then you can use that file's presence or absence as a proxy for checking the exit status of the command, and that is what I am doing with find
. I hope that's clear enough.
Looking at your filecheck.sh
example, I see that it does have such a file which can be used as a proxy as described above: ok.txt
. So the command would be something like:
find . -name 'ok.txt' -print -execdir /full/path/to/filecheck.sh \; -exec echo \;
I hope this helps.
This works based on the fact that all valid git repositories contain a directory titled .git
. The -execdir
flag to find
makes the given command run within the directory that contains the found file. So, what this command does is:
find . # find recursively, starting in the current directory...
-type d # ...files of type "directory"...
-name '.git' # ...whose name is '.git'...
-print # ...then, for each file found, print the name of the file (the dir) you found, and...
-execdir git status \; # ...from the directory containing that .git dir, run 'git status', and...
-exec echo \; # ...finally 'echo' to insert a blank line in the output for readability.
This is great for any git
commands you need to run. Unfortunately, because it depends on the presence of the .git
directory to establish which subdirs to run in, it's non trivial to extend it to run arbitrary commands.
In other words, it doesn't actually "run the command recursively in all subdirs until it finds one that works", as requested in the question post. Instead, it uses the presence of a specific file (in this case a .git
dir) to establish which subdirs to run in, and then runs the command only in those specific dirs.
I have never used hg
, but from a quick google search it appears that hg repos are similar to git repos and contain a .hg
directory in each valid repo. So this command could probably work for hg
commands also. Just replace .git
with .hg
and git status
with the hg command you want to run.
So if there is a single file or directory whose presence will guarantee you want to run the command (and that it will succeed) and whose absence will guarantee that you don't want to run the command (i.e. that the command will fail), then you can use that file's presence or absence as a proxy for checking the exit status of the command, and that is what I am doing with find
. I hope that's clear enough.
Looking at your filecheck.sh
example, I see that it does have such a file which can be used as a proxy as described above: ok.txt
. So the command would be something like:
find . -name 'ok.txt' -print -execdir /full/path/to/filecheck.sh \; -exec echo \;
I hope this helps.
It looks like all your repos are only two levels deep. If that is the case, you might try:
for i in */* ; do [ -d "$i" ] && git --git-dir="$i"/.git --work-tree="$i" status 2>/dev/null && echo "$i" && echo ; done
Credits to this SO answer and this blog post for pieces of this answer.
EDIT: Even simpler, by adapting 200_success's answer:
find . -type d -name '.git' -print -execdir git status \; -exec echo \;