Search code examples
gitgit-submodules

Git submodule prepare for sparse checkout


I have a submodule to be used with sparse checkout. Without sparse checkout I'd do

git submodule update --init <path/to/submodule>

but how to initialize the submodule repository empty without fetching it (or fetching it, but not checking it out) yet, so I can invoke

cd <path/to/submodule>
git config core.sparseCheckout true
cd <../../..>
echo <subdir-to-get> .git/modules/<path/to/submodule>/info/sparse-checkout

Unfortunately

git submodule init <path/to/submodule>

does not create the repository in .git/modules/<path/to/submodule> and the file <path/to/submodule>/.git.


Solution

  • You can try, as in here, to clone the submodule as normal repository first, and then use git submodule absorbgitdirs.

    By cloning first with a depth of 1, you don't get too many data:

    git clone --depth=1 --no-checkout an/Url <path/to/submodule>
    git submodule add an/Url <path/to/submodule>
    git submodule absorbgitdirs
    

    Then, you can modify the .git/modules/<path/to/submodule>/info/sparse-checkout

    git -C <path/to/submodule> config core.sparseCheckout true
    echo 'foo/*' >>.git/modules/<path/to/submodule>/info/sparse-checkout
    

    Finally, get only the files you want:

    git submodule update --force --checkout <path/to/submodule>
    

    As commented by Janus, one can do even better (fewer data) with a git clone --filter, which I illustrated in 2019 with "What is the git clone --filter option's syntax?":

    #fastest clone possible:
    git clone --filter=blob:none --no-checkout https://github.com/git/git
    cd git
    suburl=$(git config -f .gitmodules --get submodule.<sub>.url)
    git submodule update --init --force --checkout <sub>
    

    (Replace <sub> by the submodule name entry from your .gitmodules)