Files
holocron/plugins/git/skills/git-submodules/SKILL.md
Defame1297 af8b46cd57 chore(plugins): sync generated content mirrors
Regenerate plugins/*/skills/ from plugins/*/.apm/ after the previous
four commits, via scripts/sync-plugin-content.sh --all. The mirror is
generated output (ADR-0017) that check-plugin-content-sync's pre-push
hook diffs against .apm/; nothing here is hand-edited.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EeH8SCbcrCAQrtymkNuhKP
2026-09-07 20:43:51 +00:00

67 lines
3.1 KiB
Markdown

---
name: git-submodules
description: >
Use when managing Git submodules — the full lifecycle of a nested
repository inside a superproject — including phrasings that never say the
word, such as "add a dependency repo" or "vendor this repo inside ours".
Not multiple checkouts of one repo -> `git-worktrees`.
Not the superproject's own remotes -> `git-remotes`.
metadata:
version: "1.0.0"
category: git
source_keys:
- git-scm-submodule-docs
---
## Gotchas
- **`update` leaves the submodule in detached HEAD.** Branch inside the submodule before editing, or the work is unreachable once the pointer moves.
- **Push the submodule before the superproject.** The superproject stores only a SHA, and one missing from the submodule's remote breaks every collaborator's `update`.
- **`--recursive` is never the default.** Subcommands stop one level deep, so nested submodules go stale silently.
- **`git rm` leaves `.git/modules/<name>/` behind.** Nothing cleans it up, and it blocks re-adding a submodule there.
## Working rules
Run `rtk git` from the superproject root. Enter the submodule directory only for commits and pushes
that belong to the submodule's own history — the two repositories have independent histories, and
the same command from the wrong directory writes to the wrong one.
Before committing a superproject pointer, run `rtk git submodule status --recursive`. Prefixes: `-`
not initialized, `+` working tree differs from the recorded commit, `U` merge conflict. Add
`--cached` to read the SHAs the superproject index will record rather than the working-tree state.
A `-dirty` suffix means uncommitted changes inside the submodule, and committing the pointer over
them pins a state nobody else can reproduce.
To run one command across every submodule: `rtk git submodule foreach --recursive '<cmd>'`. Inside
`<cmd>`, Git sets `$name`, `$sm_path`, `$displaypath`, `$sha1` and `$toplevel`; append `|| :` to
continue past a failure instead of aborting the traversal. `$sm_path` and `$displaypath` name the
same directory from different vantage points — if which one you want is not obvious, read the
variable table in `references/setup-and-update.md` before writing the command.
## Dispatch
Read only the row that matches the request.
| Task | Reference |
|---|---|
| Clone a superproject with submodules; add, initialize, update or re-pin one; run a command across all of them with `foreach` | `references/setup-and-update.md` |
| Change where a submodule points — `sync`, `set-url`, `set-branch`, a local mirror override, `absorbgitdirs`, or any `.gitmodules` / `.git/config` key | `references/urls-and-config.md` |
| Remove a submodule, or `deinit` one without removing it | `references/removal.md` |
Removal and `deinit` are destructive: state what will be deleted and get confirmation before
executing.
## Output format
```yaml
operation: <clone|add|init|update|status|sync|set-url|set-branch|absorbgitdirs|deinit|remove>
status: <success|error|partial>
message: <one line; include git's own output on error>
details:
- <submodule-path>: <state>
conflicts: [<submodule-path>, ...]
next_step: <recovery action, when status is error or partial>
```