git submodule update --init --recursive: Usage & CI Errors
git submodule update --init --recursive fetches and checks out every submodule, including nested ones.
A bare clone leaves submodules empty. This one command initializes the config, clones each submodule at the pinned commit, and recurses into submodules-of-submodules - the standard CI bootstrap.
What it does
git submodule update --init reads .gitmodules, registers each submodule, clones any that are missing, and checks out the exact commit the superproject pins. --recursive applies the same process to nested submodules.
Common usage
git submodule update --init --recursive
git submodule update --init --recursive --depth 1
git submodule update --remote --merge
git -c submodule.recurse=true clone <url>Options
| Flag | What it does |
|---|---|
| --init | Initialize uninitialized submodules first |
| --recursive | Recurse into nested submodules |
| --depth <n> | Shallow-clone each submodule |
| --remote | Update to the remote tracking branch |
| --jobs <n> | Fetch submodules in parallel |
Common errors in CI
fatal: could not read Username for ‘https://...’ / "could not get a repository handle for submodule" - a private submodule needs credentials the runner lacks; use a token, insteadOf URL rewrite, or SSH keys with access. Submodules check out at a detached HEAD by design; commits there need a branch to survive.