Continue looping over submodules with the "git submodule foreach" command after a non-zero exit
Asked Answered
M

3

70

I have a project that contains many submodules. I want to loop over each submodule with the following command:

git submodule foreach npm install

And I want the script to continue looping over each submodule even if one submodule returns an error (non zero return code). Currently, a non-zero return code from running this command in any submodule will cause git to stop looping over the remaining submodules.

Any recommendations on how to accomplish this?

Multipurpose answered 1/11, 2013 at 14:38 Comment(1)
git submodule foreach 'yarn'Laissezfaire
R
145

Just make your command always return a 0 code like so:

git submodule foreach 'npm install || :'

This is taken from the manual: git help submodule:

   foreach
       Evaluates an arbitrary shell command in each checked out submodule.
       The command has access to the variables $name, $path, $sha1 and
       $toplevel: $name is the name of the relevant submodule section in
       .gitmodules, $path is the name of the submodule directory relative
       to the superproject, $sha1 is the commit as recorded in the
       superproject, and $toplevel is the absolute path to the top-level
       of the superproject. Any submodules defined in the superproject but
       not checked out are ignored by this command. Unless given --quiet,
       foreach prints the name of each submodule before evaluating the
       command. If --recursive is given, submodules are traversed
       recursively (i.e. the given shell command is evaluated in nested
       submodules as well). A non-zero return from the command in any
       submodule causes the processing to terminate. This can be
       overridden by adding || : to the end of the command.

       As an example, git submodule foreach 'echo $path `git rev-parse
       HEAD`' will show the path and currently checked out commit for each
       submodule.

The command : from help : in bash:

:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

Always succeeds :)

Rothberg answered 1/11, 2013 at 15:13 Comment(7)
git submodule foreach 'npm install || true' would do the same.Monovalent
It doesn't work on Windows. Was supposed to? Even using bash the `<command>` only try to execute the first one and breaks anyway.Thoroughfare
@MarceloFilho: Try using the git bash.Thibaud
Using git bash @MaBe... :/Thoroughfare
@MarceloFilho: please open a new question, describing the problem (so that it is reproducible by everybody), and link this question.Rothberg
On Mac use " instead of 'Palmapalmaceous
Using an EC2 with Ubuntu 18.04.3 LTS, || true failed for me, but || : worked like a charm... Thank you @RothbergBiweekly
C
5

In windows batch, you can set the return code to 0 by adding an ampersand and another command that does nothing:

git submodule foreach "npm install & echo done"

edit: originally the answer was using a semicolon to do this, which was incorrect.

Consonant answered 17/8, 2022 at 23:10 Comment(1)
Yeah, that's the part that the Git docs completely ignore: non-POSIX shells. +1Cyclades
S
2

You could see this topic.

I don't use GIT, but if you can locate the .gitmodules files, it may be easy to loop for each submodules :

<command to find all of your submodules>|while read; do
    # ... (default use $REPLY as an item)
done

Or :

while read; do
    # ...
done <<< "$(command to find all of your submodules)"

See this reminder on how to read a command output with a loop in Bash.

Shutt answered 1/11, 2013 at 14:48 Comment(2)
Please don't "parse" .gitmodules using shell ... there's a way to do it and that's: git config --file .gitmodules --get-regexp <regexp> ... which could indeed be piped into while then.Cyclades
@Cyclades this answer is +10 years old ;) (since, I became very used to use git)...Shutt

© 2022 - 2024 — McMap. All rights reserved.