Git Submodule
Use this skill as the repository's Git submodule choice and operator-workflow anchor.
The job is not to dump every git submodule command in one blob. The job is to:
- decide whether submodule is the right boundary at all,
- choose one operating mode,
- keep pinned-commit, detached-
HEAD, and hosted-platform consequences explicit, - emit the next safe commands only for that mode.
Read references/decision-matrix.md first. Read references/update-and-detached-head.md when the request involves pointer updates, detached HEAD, or editing inside the submodule. Read references/ci-and-automation.md for CI/bootstrap expectations. Read references/mode-packets-and-hosted-constraints.md for mode-specific command packets and GitHub Pages / URL-drift constraints.
If the user mainly needs:
- local branch/history cleanup, rebase, conflict recovery, or push safety → use
git-workflow - Node package delivery from Git refs, tarballs, workspaces, or publish-first flows → use
npm-git-install - repo bootstrap/task-runner automation beyond submodule mechanics → use
workflow-automation - broader environment or container setup → use
system-environment-setup
When to use this skill
- Add an external repository to a project via
git submodule add - Clone or initialize a repository that already contains submodules
- Sync a submodule back to the commit recorded by the superproject
- Advance a submodule to a tracked remote branch and commit the new pointer
- Work inside a submodule without getting surprised by detached
HEAD - Remove a submodule cleanly
- Configure GitHub Actions or other CI to fetch submodules, including private ones
- Check hosted-platform constraints such as GitHub Pages public-submodule limits
- Decide whether submodule vs subtree vs vendoring vs package delivery is the better fit
When not to use this skill
- The main problem is ordinary Git collaboration, rebasing, or history repair
- The dependency should really be a package-manager / registry artifact
- The task is broader repo bootstrap automation rather than submodule mechanics
- The request is hosted repo administration outside submodule checkout / visibility constraints
- The user wants a giant Git tutorial instead of the next safe move for one submodule situation
Instructions
Step 1: Normalize the request
Capture the request in this form first:
submodule_intake:
current_goal: decide-boundary | add | bootstrap | sync-to-pinned-commit | advance-tracked-branch | edit-inside-submodule | remove | ci-checkout | hosted-constraint | unknown
repo_role: superproject-consumer | submodule-maintainer | both | unknown
dependency_shape: external-repo | vendor-copy | subtree-candidate | package-candidate | unknown
submodule_state: absent | present-uninitialized | present-detached-head | present-on-branch | pointer-needs-update | unknown
update_intent: none | match-recorded-commit | move-to-new-upstream-commit | develop-and-push-submodule | unknown
ci_context: none | github-actions | other-ci | github-pages | unknown
auth_context: public | private-ssh | private-token | unknown
collaboration_risk: solo | shared | unknown
confidence: high | medium | lowIf context is incomplete, make the safest default explicit.
Step 2: Decide whether submodule is the right tool
Answer these before giving commands:
- Do we need a separate upstream Git history inside this repo?
- Is exact commit pinning the real requirement?
- Can the team tolerate recursive clone/bootstrap and CI checkout setup?
- Is the dependency more like a subtree, a vendored snapshot, or a published package instead?
If the answer is "not really", route away instead of forcing submodules.
Step 3: Choose exactly one primary mode
Pick one primary mode for the current run:
- boundary decision
- add-and-pin
- bootstrap-and-clone
- sync-to-pinned-commit
- advance-tracked-branch
- edit-inside-submodule
- remove-and-cleanup
- ci-checkout
- hosted-constraint
Use hosted-constraint when the user is blocked by platform rules such as GitHub Pages public-only submodules or stale submodule URL forms, rather than by ordinary local Git usage.
Step 4: Keep the operator invariants visible
These truths should survive every answer:
- A superproject records a submodule by commit, not by "latest branch".
git submodule updateusually restores the recorded commit and may leave the submodule in detachedHEAD..gitmodulesis part of the contract; branch-tracking intent belongs there whenupdate --remoteis expected.- A submodule commit is not reflected in the superproject until the submodule path is staged and committed there.
- Recursive bootstrap belongs in onboarding and automation docs if the repo depends on submodules.
- Hosted platforms may add visibility, URL, or auth constraints that normal local Git use does not reveal.
Step 5: Build the submodule brief
Return this exact structure:
# Git Submodule Brief
## Recommended mode
- Mode: boundary decision | add-and-pin | bootstrap-and-clone | sync-to-pinned-commit | advance-tracked-branch | edit-inside-submodule | remove-and-cleanup | ci-checkout | hosted-constraint
- Why this mode fits: ...
## Current state
- Superproject goal: ...
- Submodule state: ...
- Auth / CI / hosted context: ...
- Collaboration risk: solo | shared | unknown
- Confidence: high | medium | low
## Safest next move
1. ...
2. ...
3. ...
## Commands...
## Watch-outs
- ...
- ...
## Pointer / branch consequences
- ...
## Adjacent handoff
- `git-workflow` when...
- `npm-git-install` when...
- `workflow-automation` when...
Step 6: Use the mode packets, not a giant improvised command dump
Pull the exact packet from references/mode-packets-and-hosted-constraints.md.
Rules:
boundary decisionshould compare submodule with subtree / vendoring / package delivery directly.bootstrap-and-cloneandsync-to-pinned-commitmust preserve the difference between restore recorded state and upgrade pointer.advance-tracked-branchmust make branch intent explicit and commit the resulting pointer update in the superproject.edit-inside-submodulemust avoid detached-HEADcommit loss.ci-checkoutmust make private-submodule auth explicit.hosted-constraintmust call out public-only or URL-form restrictions instead of pretending hosted builds will authenticate like a local clone.
Output format
Return a short operator-style Git Submodule Brief.
Required qualities:
- pick one workflow mode
- say whether submodule is actually the right tool
- make detached-
HEAD/ pointer consequences explicit - include CI/auth or hosted-platform notes when relevant
- route away cleanly when the problem belongs to another skill
Examples
Example 1: bootstrap after clone
Input: "I cloned the repo and the vendor directory is empty. There's a .gitmodules file." Output: choose bootstrap-and-clone, recommend git submodule update --init --recursive, explain that this restores the pinned contents rather than upgrading anything, and mention private-auth caveats if applicable.
Example 2: update a tracked dependency
Input: "We track the main branch of a docs repo as a submodule and want the latest commit." Output: choose advance-tracked-branch, set or confirm submodule.<name>.branch, run git submodule update --remote <path>, then commit the pointer update in the superproject.
Example 3: choose boundary
Input: "Should this shared component repo be a submodule or subtree?" Output: choose boundary decision, compare separate-history/pinning needs against clone simplicity, and route to subtree if consumers should not deal with recursive bootstrap.
Example 4: hosted-platform constraint
Input: "Our GitHub Pages build uses a private docs-theme submodule and keeps failing." Output: choose hosted-constraint, explain the public-https:// GitHub Pages limitation, and route away from a private-submodule Pages design instead of pretending auth fixes it.
Best practices
- Start with the boundary decision, not the command list.
- Distinguish match pinned commit from advance upstream pointer.
- Treat detached
HEADas normal-but-important operator state, not as a mysterious Git bug. - Keep submodule mechanics separate from generic Git history repair.
- Make CI checkout, hosted-platform limits, and auth part of the main workflow whenever submodules are involved.
References
- Git Book: Submodules
- git-submodule documentation
- Atlassian: Git submodule
- Atlassian: Git subtree
- GitHub Actions checkout
- GitHub Pages submodule limitations