Why Would 'git Submodule Update' Skip A Submodule?

- 1 answer

I have a git repo with a single submodule sub/x. (This submodule does not contain any submodules of its own.)

In the superproject's repo, the output of git status shows the following (unstaged) modification

modified:   sub/x (new commits)

If I now run

git submodule update

...on the superproject, the following line gets printed to the terminal (and nothing more):

Skipping submodule 'sub/x'

After this, the output of git status on the superproject remains as shown above, unchanged.

(Ditto if I add --init to the git submodule update command.)

Q: How can I determine why git submodule update [--init] skips the sub/x submodule?



(Note: I've only checked a very recent Git version, and the submodule code has been undergoing changes, so this might not be the only case. But it is the only place that message can occur in the latest Git.)

Edit 2: it seems that the case below applies when the superproject's .git/config has an explicit update = none setting in it. That makes more sense than the guess I made below; it's the first half of the || expression here. I assumed there was no update = none setting though, and we were getting this from the second half (unspecified and type=NONE) and I still find that confusing.

(original answer continues below)

This message appears in the Git submodule helper code:

        if (suc->update.type == SM_UPDATE_NONE
            || (suc->update.type == SM_UPDATE_UNSPECIFIED
                && update_type == SM_UPDATE_NONE)) {
                strbuf_addf(out, _("Skipping submodule '%s'"), displaypath);
                strbuf_addch(out, '\n');
                goto cleanup;

This code fires when there's no setting set in the superproject's .git/config for the given submodule, and the update type is unspecified (git submodule update without --checkout). So:

git submodule update --checkout

would override this, as would configuring the submodule's update setting to checkout. Edit: I don't understand why the code is this way: the documentation says that the default is checkout, and behaving differently with the actual setting set to checkout, vs defaulting to checkout, does not seem to match this claim.