Files
holocron/plugins/git/.apm/skills/git-submodules/references/setup-and-update.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

Adding, initializing, updating and pinning submodules

Clone a superproject that already has submodules

git clone --recurse-submodules <url>   # Git 2.13+, one step
# or, against an existing clone
git submodule update --init --recursive

Add a dependency as a submodule

git submodule add <url> <path>
git commit -m "chore: add <name> as submodule"

add stages a .gitmodules entry and a gitlink — the commit is still required. Flags:

Flag Meaning
-b <branch> Track a branch (submodule.<name>.branch) instead of only a pinned commit
--depth <n> Shallow clone
-f Force past a gitignored path or a name conflict
--name <name> Logical name differing from the path

Initialize without cloning

git submodule init [<path>...] 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 <n> Parallel clone (defaults to submodule.fetchJobs)
-N / --no-fetch Skip the remote fetch
-f Discard local changes in the submodule working tree
--depth <n> Shallow clone
--filter <spec> Partial clone filter

Keep submodules pinned to the recorded commit

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

git submodule update --remote --merge --recursive
git commit -am "chore: update submodules to latest"

--remote requires submodule.<name>.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.