--- topic: submodules source_keys: - git-scm-submodule-docs --- # Where a submodule points, and how it is configured ## Two files, two audiences - **`.gitmodules`** — version-controlled, shared with collaborators. Defines each submodule's logical name, path, and canonical URL. - **`.git/config`** — local only, populated by `git submodule init`. Local URL overrides live here and never propagate to another clone. The submodule's own `.git` directory lives at `.git/modules//` in the superproject and is linked to the submodule's working tree by a `.git` pointer file. ## `.gitmodules` keys | Key | Purpose | |---|---| | `submodule..path` | Working tree path | | `submodule..url` | Remote URL | | `submodule..branch` | Branch used by `update --remote` | | `submodule..update` | Default update procedure | | `submodule..shallow` | Recommend a shallow clone | ## `.git/config` keys | Key | Purpose | |---|---| | `submodule..url` | Local URL override | | `submodule..update` | Local procedure override | | `submodule.fetchJobs` | Default parallelism for `update --jobs` | | `submodule.recurse` | Auto-recurse submodule updates on `pull`/`push`/etc. | ## Rebind a URL or branch ```bash git submodule sync --recursive # push .gitmodules URLs into .git/config git submodule set-url # change the canonical URL git submodule set-branch -b # set the branch used by update --remote ``` Run `sync` after an upstream rename: existing clones keep the stale URL in `.git/config` until they do. ## Override a URL locally (private mirror) ```bash git submodule init # edit .git/config: submodule..url = git submodule update ``` Local-only, invisible to collaborators, and overwritten by the next `sync`. ## Relative URLs A `../foo.git` entry in `.gitmodules` resolves against the superproject's default remote URL, not against the filesystem. It is portable across hosts that mirror the same layout and broken everywhere else. ## Custom `update` commands are security-gated A `.gitmodules` entry of `update = !some-command` is never copied into `.git/config` by `git submodule init`. That is deliberate: it stops a hostile clone from silently executing arbitrary code. Setting it locally in `.git/config` is the only way to enable it. ## Relocate an embedded `.git` directory ```bash git submodule absorbgitdirs [...] ``` Moves a submodule's own `.git` directory into `.git/modules//` and leaves a `.git` pointer file behind. Needed when a nested repository was created or copied in without going through `git submodule add`.