跨仓库 Skill 换台电脑就失效?用 Git remote 校验项目
Skill 在自己的电脑上能运行,换个工作区却找不到仓库。
例如,把本机绝对路径写进 SKILL.md 后,Agent 会照着路径读取代码和生成文档。仓库位置一变,配置就失效了。把旧用户名替换成新用户名只能解决这一次迁移;如果另一位协作者的目录结构不同,还得再改一遍。
这里涉及两个独立问题:候选目录在哪里,以及它是不是本次任务要操作的仓库。目录名相同,并不能回答第二个问题。
Skill 自带文件与业务仓库分开定位
Skill 自带的脚本、参考资料和模板,可以相对 Skill 根目录引用。例如 scripts/check.py 和 references/guide.md。这也是 Agent Skills 规范给出的文件引用方式。
业务仓库的位置则由本机配置提供。它可能在当前工作区,也可能放在另一个磁盘上。先用路径找到候选,再检查 Git remote 是否符合预期,能减少同名目录和旧副本带来的误判。
可以维护一份很小的注册表:
yaml
repositories:
service:
local_hint: workspace/backend
remote_name: origin
allowed_urls:
- git@example.com:team/backend.git
- https://example.com/team/backend.git
read_ref: origin/main
这里的地址和目录都是示例。local_hint 只提供候选位置,allowed_urls 保存团队已确认属于目标仓库的地址。read_ref 描述接下来要读取的版本,不代表路径发现时已经校验了分支。
先精确匹配允许的 remote
SSH、HTTPS、主机别名、端口和镜像会让 remote 地址变得复杂。Git 支持多种 URL 格式。对于少量固定仓库,显式列出允许的地址通常比写一段通用字符串归一化规则更容易审查。
下面的 Python 示例只检查本地配置,不访问远程服务器,也不修改仓库:
python
from pathlib import Path
import subprocess
def require_repo(candidate, allowed_urls, remote="origin"):
root = Path(candidate).expanduser().resolve()
def git(*args):
return subprocess.check_output(
["git", "-C", str(root), *args],
text=True,
).strip()
actual_root = Path(git("rev-parse", "--show-toplevel")).resolve()
if actual_root != root:
raise ValueError("请指定 checkout 根目录")
urls = git("remote", "get-url", "--all", remote).splitlines()
if not urls or any(url not in allowed_urls for url in urls):
raise ValueError("仓库 remote 不在允许列表")
return root
使用参数列表调用 Git,可以正确处理带空格的目录,避免把路径拼接成 shell 命令。--show-toplevel 用来确认候选就是仓库根目录,防止传入一个子目录后误以为找到了独立项目。
git remote get-url --all 会返回该 remote 的多个地址,代码要求这些地址都在允许列表中。Git 的 insteadOf 重写也会影响返回值,因此允许列表应根据实际读出的地址配置。git remote 文档
如果任务需要推送,再检查 git remote get-url --push --all origin。读地址与写地址应分别核对,不能用一次读取检查代替写入前检查。
找到仓库后再核对版本和写入范围
remote 检查只帮助确认本地 checkout 的配置符合预期。它不能证明文件没有被修改、代码值得信任,或当前用户拥有远程访问权限。
读取证据前,可以先记录下面几项:
bash
git -C "$repo" rev-parse HEAD
git -C "$repo" status --short
git -C "$repo" branch --show-current
如果需要读取 origin/main,还要明确它是上次抓取的本地快照,还是本次已更新的远程版本。工作区正文、HEAD 提交和远程跟踪分支可能是三个不同状态。
涉及写入时,再限定本次可以修改和提交的文件。遇到无关改动,应保留现场;需要干净基线时,可以使用隔离 worktree。发现路径的步骤不负责重置仓库,也不应该顺手替协作者提交已有改动。
用临时仓库检查定位行为
为验证上面的示例,我用临时本地仓库检查了六种情况:
| 情况 | 预期结果 |
|---|---|
| SSH 地址在允许列表中 | 返回仓库根目录 |
| HTTPS 地址在允许列表中 | 返回仓库根目录 |
| 目录名正确,remote 指向其他仓库 | 拒绝 |
| 候选路径实际是仓库里的子目录 | 拒绝 |
| 存在多个 remote URL,其中一个不被允许 | 拒绝 |
| 仓库目录名包含空格 | 正常定位 |
这六组检查通过,覆盖的是本地目录与 remote 匹配行为。它们没有验证远程认证、拉取和推送,也不能证明一个完整 Skill 已经能在所有机器上运行。
单仓库 Skill 往往只需要当前项目根目录与相对路径。需要跨仓协作时,再把本机位置、允许的仓库地址和目标版本明确配置起来。下一次换电脑,通常只需调整本机路径提示,Skill 的业务步骤就可以继续复用。