Files
holocron/plugins/git/skills/git-submodules/references/setup-and-update.md
Defame1297 ae791781c2 fix(git): restore router coverage and commands the retrofit dropped
git-workflow calls itself a router but named two of the six domains it routes to;
the other four appeared nowhere in the file. All six are now named, with a
routing table in the always-loaded body.

git-submodules lost the foreach shell-variable semantics -- only the bare names
survived, though $sm_path and $displaypath differ solely by which directory you
are in. The table is back. Its relocated commands had also dropped the rtk git
prefix its own SKILL.md mandates; 24 of them are re-prefixed. The wider rtk
inconsistency across the plugin stays with #113.

Also restores git-commits' body and footers output fields, git-branches' tag/
branch detection commands, git-worktrees' git config --worktree, pc-run's
ambiguity fallback, git-remotes' git-history boundary, and git-history's pickaxe
triggers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EJJrm5YmacbwMdzZpXcoti
2026-08-31 19:46:35 +00:00

3.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

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

Add a dependency as a submodule

rtk git submodule add <url> <path>
rtk 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

rtk 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

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 <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

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

rtk git submodule update --remote --merge --recursive
rtk 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.

Run one command across every submodule

rtk git submodule foreach --recursive '<command>'
rtk git submodule foreach 'git pull origin main || :'   # || : continues past a failure

<command> 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 <command>. $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