splitsh-lite比git subtree更适合monorepo拆分子包,因其能按路径精准导出完整历史(含原始时间戳、作者、消息),不污染reflog,支持多路径独立导出、无需remote配置;而git subtree会引入冗余merge commit、重写元信息、易混入无关路径变更。

splitsh-lite 为什么比 git subtree 更适合 Monorepo 拆分子包
因为 splitsh-lite 能按路径精准导出历史(含完整 commit 时间线),且不污染源仓库的 reflog;git subtree 导出后会残留 merge commit,且无法干净分离多个路径的历史交叠。
- 只读子包要求「提交时间戳、作者信息、commit message」全部保留,
splitsh-lite原生支持,git subtree split会重写 author/committer 时间为当前时间 - 若 Monorepo 中
packages/foo和packages/bar共享某些早期 commit,splitsh-lite可分别导出各自路径的纯净历史,而git subtree容易把对方路径的变更也带进来 -
splitsh-lite不依赖本地 Git 配置或 remote 设置,命令即用即走;git subtree需提前git remote add,稍不注意就 push 到错的 remote
用 splitsh-lite 拆出一个只读子包的实际步骤
假设你要从 monorepo 的 packages/http-client 目录拆出独立仓库 vendor/http-client,并推送到 GitHub:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 确保已安装
splitsh-lite(macOS:brew install splitsh-lite;Linux:静态二进制下载) - 在 monorepo 根目录执行:
splitsh-lite --prefix packages/http-client --branches master,main --tag-pattern 'v*' --output https://github.com/vendor/http-client.git
-
--prefix必须是路径前缀(结尾不加斜杠),否则导出内容为空;--branches要显式列出所有需同步的分支名,不能写all - 首次推送会失败(remote 无任何 commit),需先手动创建空仓库并初始化 README,或加
--force参数(慎用)
Composer 如何正确引用这些只读子包
拆完之后,子包仓库本身没有 composer.json?那它根本不会被 Composer 识别——你必须在 packages/http-client 目录下维护一份真实的 composer.json,且版本号要和 Git tag 严格对应。
- 子包的
composer.json中"name"必须是全局唯一(如"vendor/http-client"),不能沿用 monorepo 内部的临时命名 - Monorepo 主项目中,删掉
packages/http-client目录,改用"vendor/http-client": "dev-main as 1.0.0"这类版本约束,而不是"path"repo - 若子包依赖其他子包(如
http-client依赖http-contract),它们的composer.json必须声明真实包名,不能写相对路径 - 别忘了在子包仓库启用 GitHub Packages 或 Packagist 自动同步,否则
composer require时会报Could not find package vendor/http-client
常见失败场景与排查点
最常卡在「能推过去,但 Composer 找不到包」或者「tag 推了,但安装时拉的是 dev-main 而不是 v1.2.0」。
-
splitsh-lite默认不导出 annotated tag,只导 lightweight tag;而 Composer 依赖 annotated tag 解析版本。解决:用git tag -a v1.2.0 -m "release"创建,再运行splitsh-lite - GitHub 上子包仓库的默认分支名是
main,但splitsh-lite若没指定--branches main,就不会同步该分支,导致composer install报Branch main does not exist - 如果 monorepo 使用了
git worktree或浅克隆(--depth=1),splitsh-lite会因缺失历史而导出为空;必须用完整克隆 +git fetch --unshallow补全 - 子包的
composer.json若含"autoload": {"psr-4": {"Vendor\HttpClient\": "src/"}},但实际代码在packages/http-client/src/,那么拆出后路径结构不变,autoload 依然有效——这点容易误以为要改路径










