Search code examples
gitgit-submodules

git submodule update --remote vs git pull


What is the difference between running

git submodule update --remote

vs

cd <submodule directoy>
git pull

Assuming that the submodule was previously set to track some branch:

git submodule add -b master [URL to Git repo]

Solution

  • The difference is:

    • git pull will only update your submodule branch, but it can be any branch that you could have checked out yourself in that submodule repo.
    • git submodule update --remote will only update the branch registered in the .gitmodule, and by default, you will end up with a detached HEAD, unless --rebase or --merge is specified or the key submodule.$name.update is set to rebase, merge or none.

    In both cases, you still have to go back to the parent repo, add and commit the new submodule SHA1 reference.
    That is because in both instances, the SHA1 of the submodule changes, which means the gitlink (special entry in the index of the parent repo, named after to root folder of the submodule) must be added and committed.

    A git submodule update --init --remote is like:


    Can you please elaborate on "unless --rebase or --merge is specified or the key submodule.$name.update is set to rebase, merge or none"?

    I was under the impression submodules are always in detached head state and that --remote really means "match the commit pointed to by the remote branch".
    I.e, that it was translated to a commit hash first in all cases, and the submodule was then updated to that.
    But your answer makes it seem as though using rebase or merge as the update mode causes Git to point the submodule's HEAD at a branch instead of a hash, in addition to doing the update.

    The git submomdule man page is clear:

    • --rebase:

      If this option is given, the submodule’s HEAD will not be detached.
      If the key submodule.$name.update is set to rebase, this option is implicit.

    • --merge:

      If this option is given, the submodule’s HEAD will not be detached.
      If the key submodule.$name.update is set to merge, this option is implicit.

    The --remote option uses the status of the submodule’s remote-tracking branch to update the submodule, but a --merge or --rebase means the submodule will checkout a branch, instead of being detached.

    See "Mastering Git submodules / Updating a submodule in-place in the container" (2015) from Christophe Porteneuve:

    colleague (master u=) $ git submodule update --remote --rebase -- vendor/plugins/demo
    colleague (master u=) $ cd vendor/plugins/demo
    demo (master u=) $
          ^^^^^^
          # a branch is checked out
    

    You can see the same command in "Using Git submodules in your main Azure DevOps repository – Part II / " (May 2024) by Didier Van Hoye:

    Why does a Git submodule get into a head-detached situation?

    That is the default behavior when one executes git submodule update –remote. It has nothing to do with what branch you are tracking or are not tracking.

    So, what if we want to avoid the detached HEAD behaviors and ensure that our submodule’s repository always updates to the latest master branch version of its remote repository?

    You can change the submodule update behavior in the .gitmodule file, which makes the command git submodule update -–remote execute git submodule update –remote –merge or git submodule update –remote –rebase.

    git config -f .gitmodules submodule."MySubModules/SubRepoProjectOne".update merge