Search code examples
gitgit-submodulesgit-clonegit-checkout

Does updating the submodules before checking out a tag have any adverse effects?


I am trying to clone a git repo and checkout a particular tag. But I have a doubt regarding the order of commands. For now, I follow these steps:

git clone <some_repo>
cd <repo_dir>
git submodule update --init
git checkout tags/tag_001

When checking out an old tag, should one update the submodule before checking out or after?

Thanks.


Solution

  • The first git submodule update --init after the clone is necessary only to create and initialize the submodules contained in your repository. Alternatively, you could perform a git clone --recurse-submodules <some_repo> to compact the process into a single command.

    After the clone is created, initialize and clone submodules within based on the provided <pathspec>. If no=<pathspec> is provided, all submodules are initialized and cloned.

    When you checkout another commit (via a tag in your case), you need to run a second git submodule update to update the content of the submodule according to the commit recorded in the superproject. In fact, tag_001 may refer to a commit that recorded the submodule at commit X, while the branch you've checked out after the clone could refer to a commit that recorded the submodule at commit Y. If you checkout tag_001 without running git submodule update afterward, the submodule would still be checked out at commit Y, even though it should be at commit X.

    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 explanation above was done assuming that you had a single submodule with no nested submodules. If that is not the case, you should add the options --init and --recursive to both your git submodule update. This is because the first update needs to recursively initialize every submodule recorded in the commit checked out after the clone. While the second update is necessary because the commit you're switching to might contain some other (nested) submodules that are not present in the commit currently checked out. Therefore, they need to be recursively initialized.

    The previous writings (git checkout and git submodule update) can be compacted into a single command with git checkout --recurse-submodules tags/tag_001.

    Using --recurse-submodules will update the content of all active submodules according to the commit recorded in the superproject.