Files
holocron/plugins/git/.apm/skills/git-submodules/references/urls-and-config.md
Defame1297 261e5b5491 refactor(git-submodules): retrofit to the ADR-0020 context contract
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.
2026-08-30 13:10:53 +00:00

2.6 KiB

topic, source_keys
topic source_keys
submodules
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

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)

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

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.