Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Todays strategy to keep git submodule checkouts in sync with commit-IDs?

A lot of questions about automatically update submodules have been asked on StackOverflow including:

  • Is there a way to make git pull automatically update submodules?
  • Easy way to pull latest of all git submodules
  • Why doesn't git checkout automatically do git submodule update --recursive?

But it looks to me as for git submodules there is no single approach yet which works like svn up regarding svn-externals.

So since git is changing every day I dare to ask again:

Is there a (convenient) way to init and automatically update submodule checkouts (i.e. keep in sync with their corresponding submodule commit IDs) for checkout and pull (i.e. merge and rebase)?

Currently I have two approaches for this:

#1: create a post-checkout, post-merge and post-rewrite hook with the following content

#!/bin/sh
git submodule update --init --recursive

as you can already see this approach has several disadvantages:

  • it's complicated and probably needs a script to make it working reliably
  • does not work well if you use these git-hooks already
  • the commit hooks are only active on this clone (has to be re-done by everyone working on this project on every single clone)
  • setup is non-standard and will confuse others

#2: configure aliases for pull and checkout

git config --global alias.up 'pull --recurse-submodules'
git config --global alias.co 'checkout --recurse-submodules'

But this isn't nice neither:

  • it won't --init the submodules (can be solved by running pull/checkout and submodule update separately instead
  • it's non-standard and won't work with scripts and snippets
  • it's easy to forget to use up/co instead of pull/checkout
  • it works only on the local machine/user

This approach would be a bit more like I want it to be if you could do something like

git config --global pull.recurseSubmodules true
git config --global pull.initSubmodules true
git config --global checkout.recurseSubmodules true
git config --global checkout.initSubmodules true

.. but you can't, do you?

like image 772
frans Avatar asked Oct 09 '17 10:10

frans


People also ask

Do submodules automatically update?

Submodules are very static and only track specific commits. Submodules do not track git refs or branches and are not automatically updated when the host repository is updated.

How do I sync submodule?

git submodule sync synchronizes all submodules while git submodule sync -- A synchronizes submodule "A" only. If --recursive is specified, this command will recurse into the registered submodules, and sync any nested submodules within.

Does git pull also update submodules?

If you track branches in your submodules, you can update them via the --remote parameter of the git submodule update command. This pulls in new commits into the main repository and its submodules. It also changes the working directories of the submodules to the commit of the tracked branch.

How to update all initialized submodules in Git checkout?

From the git-checkout manual page: Using --recurse-submodules will update the content of all initialized submodules according to the commit recorded in the superproject. If local modifications in a submodule would be overwritten the checkout will fail unless -f is used.

What is the use of--Recurse-submodules in Git checkout?

Using the --recurse-submodules flag of git checkout can also be useful when you work on several branches in the superproject, each having your submodule pointing at different commits.

Why does git pull--recurse-submodules fail when using SuperProject?

In that case, it is possible for git pull --recurse-submodules, or git submodule update, to fail if the superproject references a submodule commit that is not found in the submodule remote locally configured in your repository. In order to remedy this situation, the git submodule sync command is required:

Why does Git checkout fail when -f is not used?

If local modifications in a submodule would be overwritten the checkout will fail unless -f is used. If nothing (or --no-recurse-submodules) is used, the work trees of submodules will not be updated. See also this relevant git mailing list message about that new option.


1 Answers

Since Git 2.13, you can do git checkout --recurse-submodules <ref> which will make sure that the working tree(s) of active submodule(s) are in sync with the submodule commit(s) recorded in the superproject at <ref>.

Since Git 2.14, you can do git pull --recurse-submodules, which will do a normal pull and will then invoke git submodule update --init --recursive (with --rebase if you pulled with --rebase), keeping active submodule(s) working tree(s) in sync with the submodule commit(s) recorded in the superproject.

Since Git 2.15, setting git config submodule.recurse true will make this the default behaviour for all commands that accept the --recurse-submodules flag, except clone and ls-files.

There is no way to make this behaviour the default without changing your configuration or using these options.


Note that doing git checkout --recurse-submodules <branch> when the current branch has no submodules and <branch> has initialized nested submodules fails before Git 2.27.

like image 129
philb Avatar answered Oct 17 '22 02:10

philb