'using "git submodule foreach" can you skip a list of submodules?

lets say I have 10 submoules:

module/1
module/2
module/3
module/4
module/5
module/6
module/7
module/8
module/9
module/10

where module/ is the top-level repo.

I want to do git submodule foreach 'git status', but I don't want to do it for submodules 4, 6 and 7.

Is there a way to do that, somthing like :

git submodule foreach --exclude="4 6 7" 'git status'

I tried doing it inside the command block using

git submodule foreach '
    if [[ $list_of_ignores =~ *"$displayname"* ]] ; then echo ignore; fi
'

update - removed --exclude="4 6 7" that was accidently in there

But I get errors saying eval [[: not found - I am assuming this is because it is using /bin/sh instead of /bin/bash? - not sure...



Solution 1:[1]

As the docs say, foreach executes shell commands,

foreach [--recursive] <command>
    Evaluates an arbitrary shell command in each checked out submodule. The 
    command has access to the variables $name, $sm_path, $displaypath, $sha1
    and $toplevel

so use the shell:

 git submodule foreach 'case $name in 4|6|7) ;; *) git status ;; esac'

If the syntax looks strange to you, look up the syntax for bash's case statements. The above, if written in a script with line breaks, would be:

case $name in # $name is available to `submodule foreach`
    4|5|6)
     ;;
    *)     # default "catchall"
     git status 
    ;;
esac

Solution 2:[2]

This might probably be a terrible workaround but it works for my specific case.

git submodule foreach --recursive will only iterate over the existing folder (non-recursive as well), so I usually just delete the folders to skip (assuring firstly that everything is committed/stashed!).

So in case of the following sub-module structure:

tree
.
??? 1
??? 2
?   ??? 3
?   ??? 4
??? 5
?   ??? 6
?   ?   ??? 7
?   ??? 8
??? 9

If I want to execute foo command on every submodule except 5 and children I just delete the 5 folder:

rm -rf 5
git submodule --recursive foo             # 5, 6, 7, 8 won't be touched.
git submodule --update --init --recursive # Restore the removed folders.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrew
Solution 2 S?awomir Kwa?niak