A plain `git clone` does not download submodules. You get the main repository, and each submodule folder is there but empty. One extra flag, or one extra command, fills them in.

For how submodules are structured, see the [git submodule command reference](/git/commands/git-submodule).

## Clone a repository with its submodules

Add `--recurse-submodules` when you clone:

```bash
git clone --recurse-submodules https://github.com/your-org/your-repo.git
```

Git clones the main repository, then clones every submodule and checks out the commit the main repository points to. Nested submodules (submodules inside submodules) are included.

## You already cloned it, and the folders are empty

Run this from the root of the repository:

```bash
git submodule update --init --recursive
```

- `--init` registers any submodules that have not been set up on this machine.
- `update` clones them and checks out the recorded commit.
- `--recursive` repeats the process for submodules inside submodules.

## Pull changes that include submodule updates

`git pull` updates the main repository. If a teammate moved a submodule to a newer commit, update your copy with:

```bash
git pull --recurse-submodules
```

or run `git submodule update --init --recursive` after a normal pull. If you want a submodule to move to the newest commit on its own remote branch, rather than the commit the main repository records, use `git submodule update --remote` instead. That is a deliberate change to the pinned commit, so commit the result afterwards.

## Make recursion the default

To stop typing the flag on every pull, set it once for the repository:

```bash
git config submodule.recurse true
```

Commands that support `--recurse-submodules`, such as `pull` and `checkout`, will then use it by default. Add `--global` to apply it to every repository on your machine.

This setting does not change `git clone`. A clone still needs `--recurse-submodules`, even with the setting on.

## Private submodules and CI

A submodule is a separate repository, so it needs its own access. If a private submodule fails with an authentication error, the account or key that clones the main repository does not have access to the submodule. On GitHub, one deploy key can only belong to one repository, so a main repository with private submodules often needs a machine user that can read all of them.

Our guide to [submodule errors during deployment](https://www.deployhq.com/blog/using-submodules-in-deploy) walks through the authentication failures and the fixes for the main providers. If a clone fails with a missing submodule path, see [adding files at the path of a previous submodule](/git/faqs/add-files-git-submodule-path).

## Quick reference

| Goal | Command |
|------|---------|
| Clone with submodules | `git clone --recurse-submodules <url>` |
| Fill in submodules after a plain clone | `git submodule update --init --recursive` |
| Pull and update submodules | `git pull --recurse-submodules` |
| Move submodules to their latest remote commit | `git submodule update --remote` |
| Recurse by default in this repository | `git config submodule.recurse true` |

Deploying a project with submodules? [DeployHQ](https://www.deployhq.com/features/automatic-deployments) can deploy it whenever you push.
