--- topic: submodules source_keys: - git-scm-submodule-docs --- # Adding, initializing, updating and pinning submodules ## Clone a superproject that already has submodules ```bash rtk git clone --recurse-submodules # Git 2.13+, one step # or, against an existing clone rtk git submodule update --init --recursive ``` ## Add a dependency as a submodule ```bash rtk git submodule add rtk 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 `rtk 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 `rtk 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 rtk git submodule update --recursive # after every rtk git pull rtk git config submodule.recurse true # or do it automatically on pull/push/checkout ``` ## Move the pin forward to the tracked branch tip ```bash rtk git submodule update --remote --merge --recursive rtk git commit -am "chore: update submodules to latest" ``` `--remote` uses `submodule..branch` when it is set; 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`. ## Run one command across every submodule ```bash rtk git submodule foreach --recursive '' rtk git submodule foreach 'git pull origin main || :' # || : continues past a failure ``` `` runs inside each submodule's own working tree, so the git calls in it are the submodule's own — that is the one place a bare `git` is correct. Append `|| :` to keep the traversal going instead of aborting at the first failure. Git exports five shell variables into ``. `$sm_path` and `$displaypath` name the same directory from different vantage points and are not interchangeable: | Variable | Meaning | |---|---| | `$name` | Logical submodule name (the `.gitmodules` section name, which need not match the path) | | `$sm_path` | Path relative to the superproject root | | `$displaypath` | Path relative to the current working directory | | `$sha1` | Commit SHA the superproject has recorded for this submodule | | `$toplevel` | Absolute path of the superproject's root |