In some projects we might need to have one or more third party libraries/packages or even our external reusable package(s) from a different repository.
In this case we can use git submodule to manage a package within a source controlled project with a separate remote source that is pointed to a specific commit (on that external external repo).
To initialize, inspect or update git submodules, use:
$ git submodule
$ git submodule --help
To add a git submodule use:
$ git submodule add <url>
// or
$ git submodule add <url> relative/optional/path/
When submodule added, all package file will be downloaded into the related directory and a new file .gitmodules
will be created, which might look like:
[submodule "relative/path"]
path = relative/path
url = git@github.com:<profile>/<project>.git
Note: there will be used a relative path without trailing slashes.
But, if you clone a repo with an existing submodule, files from submodules will not be pulled automatically, so to download all the content you might use next commands:
$ git pull --recurse-submodules
// or
$ git submodule update --init
// or
$ git pull && git submodule update --init --recursive
// or
$ git clone --recurse-submodules git@github.com:<profile>/<project>.git
Warning: In case if you’re working with legacy code where there is a package with repo but not added through the git submodule directive:
// check using:
$ git submodule
// and next error should be displayed:
>> fatal: no submodule mapping found in .gitmodules for path 'relative/path/to/submodule'
and you wish to correct it by adding as a submodule, an error will be raised:
'relative/path/to/submodule' already exists in the index
In this case one way out is to create a .submodules
file manually, add related entries as a sample above.
Note: On each submodule updates you’ll be forced to update main repo, as it saves the pointer for each submodule commit.