Search code examples
gitgit-submodulesgit-detached-head

Should I checkout to a branch before updating changes on a remote submodule in Git?


I have my main project called "MP" and it depends on a submodule repo called "SM" (just fictional names for this question).

I just have my 'main' branch on MP and a 'main' branch on SM.

I just 'connected' my main repo with its submodule repo by

git submodule add URL
git commit -am "Add submodule SM"
git push origin main

In my submodule I have 3 commits, so if I access to the submodule local directory I have this:

059140e (HEAD -> main, origin/main, origin/HEAD) Commit 3
eaebed2 Commit2
81e7318 Initial commit

Everything is fine for me at this point (or at least I think so).

The problem is when I try to clone the repo with its submodule, I create a new directory and go on:

git clone URL  # Clone parent repo (MP)
git remote update --init --recursive  # All the show about initialize fetch and checkout ALL the submodules and nested submodules

Again, in my submodule I have 3 commits, so if I access to the submodule local directory I have this:

12a51e4 (HEAD, origin/main, origin/HEAD, main) Commit 3
d190a20 Commit 2
f1311ed Initial commit

And git status shows what is reflected here, I have 'detached head state'.

And this is not equal to the past log (where HEAD is pointing to main).

So here onwards I have some doubts, because, what about if someone makes some changes to the submodule (add for example adds one extra commit), and I want to 'update the reference to the main project to the submodule' so the reference now has the new commit, but I'm afraid of what may happen if I do this with this 'detached head' in the submodule.

Should I do a git checkout main inside the local submodule directory before updating the submodule with:

git submodule update --remote

Solution

  • And git status shows what is reflected here, I have 'detatched head state'. [...] So here onwards I have some doubts [...]

    Sadly, by default, the update command brings a submodule into the detached HEAD state, whether a branch is checked out or not. In this scenario, the submodule is aligned from the remote with the content of the default branch specified in the .gitmodules file under submodule.<name>.branch, or with the remote's HEAD.

    If you want to update a submodule with new changes without entering the detached HEAD state, you need to checkout the desired branch and run the update command with either the --merge

    This option is only valid for the update command. Merge the commit recorded in the superproject into the current branch of the submodule. If this option is given, the submodule’s HEAD will not be detached.

    or --rebase option.

    This option is only valid for the update command. Rebase the current branch onto the commit recorded in the superproject. If this option is given, the submodule’s HEAD will not be detached.

    So, to answer your question

    Should I checkout to a branch before updating changes on a remote submodule in Git?

    If you don't want to enter the detached HEAD state and merge new changes into a branch or rebase a branch on top of those changes, yes you should definitely checkout a branch and run one of these two versions of the update command.

    git submodule update --remote --merge
    
    # or
    
    git submodule update --remote --rebase
    

    On a side note, I think you wanted to write "git submodule update --init --recursive" instead of "git remote update --init --recursive"

    The problem is when I try to clone the repo with its submodule

    git clone URL  # Clone parent repo (MP)
    git remote update --init --recursive