--- topic: submodules source_keys: - git-scm-submodule-docs --- # Adding, initializing, updating and pinning submodules ## Clone a superproject that already has submodules ```bash git clone --recurse-submodules # Git 2.13+, one step # or, against an existing clone git submodule update --init --recursive ``` ## Add a dependency as a submodule ```bash git submodule add git commit -m "chore: add as submodule" ``` `add` stages a `.gitmodules` entry and a gitlink — the commit is still required. Flags: | Flag | Meaning | |---|---| | `-b ` | Track a branch (`submodule..branch`) instead of only a pinned commit | | `--depth ` | Shallow clone | | `-f` | Force past a gitignored path or a name conflict | | `--name ` | Logical name differing from the path | ## Initialize without cloning `git submodule init [...]` copies submodule URLs from `.gitmodules` into `.git/config` and does nothing else. This is the point at which a local URL override can be edited before any fetch happens. If a local mirror override is wanted, read `references/urls-and-config.md` before running `update`. Use `update --init` to run both steps at once. ## Update `git submodule update --init --recursive` is the common case: it clones what is missing and checks out the commit the superproject recorded, in detached HEAD. | Flag | Meaning | |---|---| | `--init` | Run `init` first, avoiding a separate step | | `--remote` | Use the submodule's remote branch tip instead of the superproject's recorded commit | | `--checkout` | Detached HEAD at the recorded commit (default) | | `--rebase` | Rebase the current branch onto the recorded commit | | `--merge` | Merge the recorded commit into the current branch | | `--recursive` | Operate on nested submodules | | `--jobs ` | Parallel clone (defaults to `submodule.fetchJobs`) | | `-N` / `--no-fetch` | Skip the remote fetch | | `-f` | Discard local changes in the submodule working tree | | `--depth ` | Shallow clone | | `--filter ` | Partial clone filter | ## Keep submodules pinned to the recorded commit ```bash git submodule update --recursive # after every git pull git config submodule.recurse true # or do it automatically on pull/push/checkout ``` ## Move the pin forward to the tracked branch tip ```bash git submodule update --remote --merge --recursive git commit -am "chore: update submodules to latest" ``` `--remote` requires `submodule..branch`; without it Git falls back to the remote's default branch. Commit the superproject afterwards or the new pin is lost on the next `update`.