safe-path-migration
Skill0 starsChanged 4 months agoApache-2.0View on GitHub
根目录改名/移动后,安全批量更新全树绝对路径引用。只替换「路径形式」的旧根前缀,保留品牌语义名、GitHub URL、历史旧根引用;规避备份目录递归陷阱;用 robocopy /MIR 强制清空长路径深层残留。适用于任何「D:\OldRoot → D:\NewRoot」或「嵌套到新父目录」的目录重构。
- Deletes or force-pushes
In this repository6 other files it gives its agents.
- archiveSkill
- bifrostSkill
- context-guardSkill
- kernel-securitySkill
- origin-thinkingSkill
- semantic-stitching-guardSkill
The file
Files
safe-path-migration — 安全路径引用迁移
当需要重命名或移动一个被大量文件硬编码引用的根目录时,盲目全局替换 OldRoot → NewRoot 会破坏品牌语义、仓库 URL、历史文档。本技能给出经过实战验证的安全流程。
何时使用
- 根目录改名(如
D:\OldRoot → D:\NewRoot)。 - 目录整体迁移/嵌套(如把
A、B两个顶层目录移入D:\Parent\,变成D:\Parent\A\…)。 - 任何「大量文件含旧绝对路径、需重定向」的场景。
核心原则:区分三类字符串,绝不盲替
对扫描到的每个 OldRoot 出现,先判定类别:
- 路径形式
D:\OldRoot\…或D:/OldRoot/…→ 按映射表替换(这是要改的)。 - 品牌语义裸名
OldRoot(不跟路径分隔符,如「OldRoot 平台」)→ 保留不动。 - 仓库/站点 URL
github.com/user/OldRoot、username.github.io/OldRoot→ 保留不动(由仓库名决定,不随本地文件夹变)。 - 历史旧根
D:\OldRoot_OldSuffix\…(不同字符串,如下划线旧命名)→ 保留不动(属历史记录)。
判定靠正则:只匹配 D:[\\/]OldRoot[\\/](要求紧接路径分隔符),天然排除上述 2/3/4。
步骤
- 枚举首段,建立证据化映射(不要猜):
grep -rhoE 'D:[\\/]OldRoot[\\/][^\\/[:space:]"'"'"'()<>]*' ROOT | sed 's#...##' | sort | uniq -c看OldRoot/之后第一层目录是什么,据此决定每个首段重定向到哪:- 仍在原仓库内的 →
NewRoot\同段 - 已迁出的子目录(如
Assets、Workspace等已移到别处的)→ 正确新位置 - 已改名的子目录 → 新名称
映射必须最长优先(先匹配
Projects\SubProject再匹配Projects),避免短路。
- 仍在原仓库内的 →
- 写替换脚本(Python),要点:
- 扫描多个 root(
os.walk),EXCLUDE_DIRS = {'.git','.workbuddy','node_modules','__pycache__',...}。 - 备份根目录必须放在所有扫描 root 之外(如
D:\_pathfix_backup\),且在 walk 中对含_pathfix_backup的子串做dirnames[:] = [d for d in dirnames if '_pathfix_backup' not in d]排除——否则备份副本会被自身递归,路径无限嵌套、崩溃。 - 替换逻辑:对每行依次应用映射(路径分隔符
\与/都兼容);只改路径形式,品牌/URL/历史不动。 - 默认 dry-run 打印报告;
--apply才写文件(写前shutil.copy2备份到树外)。
- 扫描多个 root(
- 先 dry-run,人工核对报告:确认每条
+新路径合理、无+行残留OldRoot(残留必为历史OldRoot_Suffix之类,确认 benign)。 --apply,然后复验:grep -rnoE 'D:[\\/]OldRoot[\\/]' ROOT | grep -v '/.git/' | grep -v '/.workbuddy/' | grep -v '_pathfix_backup'→ 应为 0。- 清理临时产物:删脚本、报告、树外备份、
D:\_empty_del(若有)。
致命坑:长路径深层残留删不掉
rm -rf、Python shutil.rmtree、甚至 \\?\ 前缀在某些沙箱/虚拟化文件系统上会因 260 字符路径限制静默失败或报 WinError 123,导致损坏的嵌套备份目录删不净。
解法(已验证):用 robocopy /MIR 镜像一个空目录来清空——
python -c "import os; os.makedirs(r'D:\_empty_del', exist_ok=True)"
robocopy "D:/_empty_del" "<目标深层目录>" /MIR /R:0 /W:0 /NFL /NDL /NP
rm -rf "<目标深层目录>"
rm -rf "D:/_empty_del"robocopy 是 LongPathAware,能删穿深层嵌套。空目录源用 Python 在目标盘建(避免 Git Bash /tmp 映射问题)。
第二轮迁移(嵌套到新父目录)
当把 A 和 B 移入 Parent(Parent\A\…、Parent\B\…)时,映射变为:
D:\A\…→D:\Parent\A\…D:\B\…→D:\Parent\B\…注意是二级路径Parent\A\…,不是旧根Parent\…直接裸用。复用本技能的脚本时仅需改映射表与 root 列表(root 改成D:\Parent或分别扫D:\A、D:\B)。
不适用 / 注意
- 工具自动生成的运行产物(
runs/latest/*.json等)内的旧路径,属重算产物,不手改。 - 私有仓库内的历史/结构文档若把旧根作为「历史记录」叙述,按类别 4 保留。
- 改完后务必
git status确认改动面符合预期。
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

