Search code examples
gitgit-submodules

Is it possible to specify which commits to clone with git submodules?


I am using .gitmodules file to specify a git submodule for my main repo:

[submodule "SUBMODULE"]
    path = ...
    url = ...

And then in the command line: git clone MAINREPO --recursive.

Is it possible to specify which commit of the submodule to check out in the cloning command?


Solution

  • The short answer to your question is: No way. The information is written in the superproject in commits that stores info about submodule change. Every time one runs

    git clone --recursive superproject-url
    

    or

    git checkout --recursive some-old-commit
    

    Git looks up commits of submodules in the HEAD or the old commit being checked out and checkout stored commits of the submodules.

    If you want to change what commit is stored in the HEAD: go to the locally cloned submodule, checkout the commit, return to the superproject, add and commit the change in the submodule, push:

    cd subdir
    git checkout branch-tag-or-ID
    cd .. # back to the superproject
    git add subdir
    git commit -m "Change in subdir" subdir
    

    If the commit in the submodule you want to change to is the HEAD you can do instead in the superproject

    git submodule update --remote subdir
    git commit -m "Change in subdir" subdir
    

    Instead of a command line options you can do (with a shell script or a git alias) git clone --recursive && cd subdir && git checkout commit-ID. That's the only way. something like

    # .gitconfig
    [alias]
    clone-sub = "!f() { git clone --recursive \"$1\" && cd \"$2\" && git checkout \"$3\"; }; f"
    

    Usage: git clone-sub superproject-url submodule-path commit-ID