关于 git-submodule
git-submodule 是用于判断是否采用 Git 子模块并指导相关操作流程的技能,重点说明提交固定、分离 HEAD 的影响,以及 CI 和托管平台限制。
主要功能
- 01选择子模块或其他依赖边界
- 02指导添加、克隆、同步、更新和移除
- 03说明固定提交与分离 HEAD
- 04涵盖 CI 检出和托管平台限制
适用场景
- 01比较子模块、子树、直接纳入代码或软件包
- 02恢复仓库记录的子模块提交
- 03推进子模块分支并记录指针更新
- 04准备 CI 检出或检查托管平台限制
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ akillness/ jeo-skills --skill git-submodule安装后在 Claude Code 中输入/git-submodule确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
SKILL.toonevals/evals.jsonreferences/ci-and-automation.mddecision-matrix.mdmode-packets-and-hosted-constraints.mdupdate-and-detached-head.md详细介绍
Git 子模块
将此技能用作仓库的Git 子模块选型与操作工作流锚点。
这项工作的目的不是把所有 git submodule 命令一股脑地列出来,而是:
- 判断子模块是否确实是合适的边界,
- 选择一种操作模式,
- 明确说明固定提交、分离的
HEAD和托管平台方面的影响, - 仅针对该模式给出下一步安全命令。
请先阅读 references/decision-matrix.md。
当请求涉及指针更新、分离的 HEAD 或在子模块内编辑时,请阅读 references/update-and-detached-head.md。
有关 CI/引导流程的预期,请阅读 references/ci-and-automation.md。
有关特定模式的命令包以及 GitHub Pages/URL 漂移限制,请阅读 references/mode-packets-and-hosted-constraints.md。
如果用户主要需要:
- 清理本地分支/历史、变基、解决冲突或确保安全推送 → 使用
git-workflow - 从 Git 引用、tar 包、工作区或先发布再安装的流程交付 Node 包 → 使用
npm-git-install - 超出子模块机制范围的仓库引导/任务运行器自动化 → 使用
deployment-automation - 更广泛的环境或容器设置 → 使用
system-environment-setup
何时使用此技能
- 通过
git submodule add将外部仓库添加到项目 - 克隆或初始化已包含子模块的仓库
- 将子模块同步回超级项目记录的提交
- 将子模块推进到受跟踪的远程分支,并提交新的指针
- 在子模块中操作,避免因分离的
HEAD而措手不及 - 正确移除子模块
- 配置 GitHub Actions 或其他 CI 来获取子模块,包括私有子模块
- 检查托管平台限制,例如 GitHub Pages 对公开子模块的限制
- 判断子模块、子树、供应商快照或软件包交付哪种方式更合适
何时不使用此技能
- 主要问题是常规 Git 协作、变基或修复历史
- 依赖实际上应该是软件包管理器/注册表中的制品
- 任务涉及的是更广泛的仓库引导自动化,而非子模块机制
- 请求涉及子模块检出/可见性限制之外的托管仓库管理
- 用户想要冗长的 Git 教程,而不是针对某个子模块情况给出的下一步安全操作
说明
步骤 1:规范化请求
首先按以下格式记录请求:
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 | low
如果上下文不完整,请明确说明最安全的默认做法。
步骤 2:判断子模块是否合适
给出命令前,请先回答以下问题:
- 我们是否需要在此仓库内保留独立的上游 Git 历史?
- 精确固定提交是否是实际需求?
- 团队能否接受递归克隆/引导流程及 CI 检出配置?
- 该依赖是否更适合用子树、供应商快照或已发布的软件包?
如果答案是“其实不需要”,请转而采用其他方案,不要强行使用子模块。
步骤 3:只选择一种主要模式
为当前操作选择一种主要模式:
- 边界决策
- 添加并固定
- 引导并克隆
- 同步到固定提交
- 推进受跟踪分支
- 在子模块内编辑
- 移除并清理
- CI 检出
- 托管平台限制
当用户受平台规则阻碍(例如 GitHub Pages 仅允许公开子模块,或子模块 URL 格式已过时),而非受常规本地 Git 操作阻碍时,请使用 hosted-constraint。
第 4 步:让操作层面的不变量始终清晰可见
每次回答都应保留以下事实:
- 超级项目记录子模块的 提交,而不是“最新分支”。
git submodule update通常会还原已记录的提交,并可能让子模块处于分离的HEAD状态。.gitmodules是契约的一部分;如果预期使用update --remote,分支跟踪意图应写在其中。- 只有将子模块路径暂存并在超级项目中提交后,子模块提交才会反映到超级项目中。
- 如果仓库依赖子模块,引导和自动化文档应包含递归初始化步骤。
- 托管平台可能会带来普通本地 Git 用法无法体现的可见性、URL 或身份验证限制。
第 5 步:编写子模块概要
按以下确切结构返回:
# 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
```bash
...
注意事项
- ...
- ...
指针 / 分支的影响
- ...
相邻交接
git-workflow在……时npm-git-install在……时deployment-automation在……时
### Step 6: Use the mode packets, not a giant improvised command dump
Pull the exact packet from [references/mode-packets-and-hosted-constraints.md](references/mode-packets-and-hosted-constraints.md).
Rules:
- `boundary decision` should compare submodule with subtree / vendoring / package delivery directly.
- `bootstrap-and-clone` and `sync-to-pinned-commit` must preserve the difference between **restore recorded state** and **upgrade pointer**.
- `advance-tracked-branch` must make branch intent explicit and commit the resulting pointer update in the superproject.
- `edit-inside-submodule` must avoid detached-`HEAD` commit loss.
- `ci-checkout` must make private-submodule auth explicit.
- `hosted-constraint` must 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
1. Start with the boundary decision, not the command list.
2. Distinguish **match pinned commit** from **advance upstream pointer**.
3. Treat detached `HEAD` as normal-but-important operator state, not as a mysterious Git bug.
4. Keep submodule mechanics separate from generic Git history repair.
5. Make CI checkout, hosted-platform limits, and auth part of the main workflow whenever submodules are involved.
## References
- [Git Book: Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)
- [git-submodule documentation](https://git-scm.com/docs/git-submodule)
- [Atlassian: Git submodule](https://www.atlassian.com/git/tutorials/git-submodule)
- [Atlassian: Git subtree](https://www.atlassian.com/git/tutorials/git-subtree)
- [GitHub Actions checkout](https://github.com/actions/checkout#checkout-multiple-repos-private)
- [GitHub Pages submodule limitations](https://docs.github.com/en/pages/getting-started-with-github-pages/using-submodules-with-github-pages)
评论
支持 Markdown