Home > other >  How do you initialize new submodules after a pull without affecting the pre-existing ones?
How do you initialize new submodules after a pull without affecting the pre-existing ones?

Time:04-11

After pulling, I would like to initialize all new submodules recursively with a single command.

The issue with using git submodule update --init --recursive is that it also resets which commit my pre-existing submodules are pointing to.

CodePudding user response:

git submodule update --init --recursive is indeed the right command to use to initialize all submodules, recursively. The submodules repositories will be cloned, and the commit recorded in the superproject will be checked out.

This is correctly documented in git-submodule(1):

Update the registered submodules to match what the superproject expects by cloning missing submodules, fetching missing commits in submodules and updating the working tree of the submodules. The "updating" can be done in several ways depending on command line options and the value of submodule.<name>.update configuration variable. The command line option takes precedence over the configuration variable. If neither is given, a checkout is performed. [...]

checkout: the commit recorded in the superproject will be checked out in the submodule on a detached HEAD.

[...]

If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the submodule with the --init option.

If --recursive is specified, this command will recurse into the registered submodules, and update any nested submodules within.

Note that you can get the same behaviour by simply using git clone --recurse-submodules.

CodePudding user response:

This is far enough off the beaten path that I think you're going to have to script it. Almost all Git commands started out as scripts and could still be done that way.

If you always keep all submodules active then git submodule foreach --recursive is your starting point, but if you're selective about which submodules get checked out at all you're going to have to do more than just

git submodule foreach --recursive -q 'echo git -C $PWD checkout `git rev-parse @`'

(which is actually an example in the git submodule docs) and run the checkouts that prints to restore what you care about after the recursive update does too much.

CodePudding user response:

Now you changed your question completely and you are asking (emphasis mine):

After pulling, I would like to initialize all new submodules recursively with a single command.

The issue with using git submodule update --init --recursive is that it also resets which commit my pre-existing submodules are pointing to.

It would be nice to have more details here, including an MCVE (in the case of Git questions, that usually means the complete set of Git commands to run, starting from git init/git clone). If not your readers are left to guess your exact situation (and with submodules, there are a lot of possibilities).

To initialize new submodules only, you first would have to find out if there are any new submodules that were brought by the git pull you did. Something like the following should list submodules (grep 160000) that have been added (--diff-filter=A) since the commit you were on before pulling (ORIG_HEAD..):

git log --format=%h ORIG_HEAD.. --summary --diff-filter=A | \grep 160000 | awk '{print $4}'

You could then use git submodule update with this list of submodules to only initialize these ones:

git submodule update --init --recursive $(git log --format=%h ORIG_HEAD.. --summary --diff-filter=A | \grep 160000 | awk '{print $4}' | tr \\n ' ')

Note that it's not clear from your question in what state are your pre-existing submodules, the ones that you want to avoid changing. Are they "modified" (i.e. you checked out a different commit in the submodule, but did not run git add in the superproject yet), "added" (i.e. you checked out a different commit in the submodule, ran git add in the superproject, but did not commit that change in the superproject yet) or if on the contrary your working directory is completely clean, but you did commit submodule changes since your last pull. Depending on that and what you want the end result to look like, simply running git submodule update --init --recursive --merge or git submodule update --init --recursive --rebase might fill your needs...

  • Related