不能“剥离分支”,只能剥离目录或重写历史;Git分支本质是轻量指针,无独立历史,实际操作仅有按路径切历史(如git filter-repo --path)或按状态建新库(如git checkout --orphan)两条路径。

如果你看到某个分支(比如 feature/payment)里改了一堆文件、提交了十几条记录,想把它单独拎出来当新项目用,别被“分支”二字误导。Git 没有“分支级历史隔离”这回事。真正可操作的,只有两条路:按路径切历史(保留真实改动),或按状态建新库(丢掉所有历史)。选哪条,取决于你是否需要那些 commit 记录。
git subtree split 只生成空提交?检查 --prefix 是否写对
这是最常踩的坑:命令跑完,新分支里只有空提交,git log 看不到任何内容。
-
--prefix必须以斜杠结尾,比如你要拆src/core/,就得写--prefix=src/core/,写成--prefix=src/core就匹配失败 - 路径大小写必须和历史中完全一致 —— 如果某次提交里是
Src/core/,你写src/core/就找不到 - 该目录必须在至少一次提交中真实存在过;如果它只在最近 3 次提交里才有,那更早的提交会被跳过(不是报错,是静默忽略)
- 别用
git subtree push直接推 —— 它会把父仓库的完整 commit hash 带过去,新仓库里能看到其他路径的空壳记录
git filter-repo --path 是目前最干净的路径剥离方案
相比已弃用的 git filter-branch,git filter-repo 更快、更安全,且默认不保留无关路径的历史痕迹。
GitHub 仓库备份技能 - 将 OpenClaw 工作空间自动或手动备份至 GitHub 私有仓库。支持自动定时备份和手动交互式配置,引导完成 Token 配置、仓库创建、首次备份及定时任务设置。用途:(1) 首次设置 (2) 日常备份。
- 先克隆原仓库(不要在原 repo 上直接操作):
git clone <url> temp-split - 进目录后执行:
git filter-repo --path src/cli/ --path-rename src/cli/:(末尾冒号表示提升为根目录) - 注意:
--path是“只留这个路径”,--invert-paths才是“删掉这个路径” - 执行后,
.git会自动瘦身,不需要手动gc或reflog expire - 如果原目录结构很深(如
packages/foo/),--path-rename可以重命名目标路径,避免新仓库里还带着多层前缀
只想保留最新代码、彻底丢掉历史?--orphan 是最干脆的做法
适用于重构后想从零开始、或敏感信息已污染整个历史但又懒得逐条清理的场景。
-
git checkout --orphan new-main创建无历史分支 -
git add -A把当前工作区所有文件加进来(包括.gitignore和README) -
git commit -m "Initial commit"提交唯一一次记录 -
git branch -D main删除旧分支,再git branch -m new-main main - 远程推送必须加
--force:git push -f origin main
注意:--orphan 不处理子模块、不保留 gitattributes 配置、也不继承原 repo 的 hooks —— 它真的就是一张白纸。
真正麻烦的从来不是命令本身,而是后续维护:拆出来的仓库如果还要和原 repo 同步修改,Git 不会自动帮你 merge 或 detect 冲突。要么靠人工约定(比如只允许在子仓库改代码),要么引入 CI 脚本做定期 subtree pull,否则很快就会出现历史分叉、文件覆盖、甚至二进制冲突。

















