Description 480 -> 248 chars, body 1011 -> 347 words. The single submodules.md splits into setup-and-update, urls-and-config, and removal. Restores three regressions the first pass introduced: 'repointing' as the trigger for the URL branch, which had none while the boundary clause steered those queries to git-remotes; clone and absorbgitdirs in the output enum, which dispatch still routed to; and status --cached, the flag that makes the pre-commit pointer gate verifiable.
80 lines
2.6 KiB
Markdown
80 lines
2.6 KiB
Markdown
---
|
|
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/<name>/` in the superproject and is
|
|
linked to the submodule's working tree by a `.git` pointer file.
|
|
|
|
## `.gitmodules` keys
|
|
|
|
| Key | Purpose |
|
|
|---|---|
|
|
| `submodule.<name>.path` | Working tree path |
|
|
| `submodule.<name>.url` | Remote URL |
|
|
| `submodule.<name>.branch` | Branch used by `update --remote` |
|
|
| `submodule.<name>.update` | Default update procedure |
|
|
| `submodule.<name>.shallow` | Recommend a shallow clone |
|
|
|
|
## `.git/config` keys
|
|
|
|
| Key | Purpose |
|
|
|---|---|
|
|
| `submodule.<name>.url` | Local URL override |
|
|
| `submodule.<name>.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 <path> <url> # change the canonical URL
|
|
git submodule set-branch -b <branch> <path> # 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.<name>.url = <mirror-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 [<path>...]
|
|
```
|
|
|
|
Moves a submodule's own `.git` directory into `.git/modules/<name>/` and leaves a `.git` pointer
|
|
file behind. Needed when a nested repository was created or copied in without going through
|
|
`git submodule add`.
|