
mise bootstrap repos apply 完全指南声明式 Git 仓库检出的克隆与收敛【免费下载链接】misedev tools, env vars, task runner项目地址: https://gitcode.com/GitHub_Trending/mi/misemise bootstrap repos apply是 misedev tools, env vars, task runnerbootstrap 体系中专用于处理 Git 仓库检出的命令负责把[bootstrap.repos]中声明的仓库克隆到目标路径或在已存在时将其收敛到声明的ref状态。本文以 docs/cli/bootstrap/repos/apply.md 为核心骨架结合 docs/bootstrap/repos.md 与源码 src/system/repos.rs、src/cli/system/install.rs 的实现细节完整讲解配置写法、命令参数、安全语义与状态机读完后你可以把 dotfiles、开发工具源码等 Git 仓库纳入一条可重复执行的 bootstrap 流水线。一、功能定位apply在 bootstrap 流程中的角色mise bootstrap repos apply的官方定位是Clone and converge git repos from[bootstrap.repos]克隆并收敛[bootstrap.repos]中声明的 Git 仓库。它属于mise bootstrap repos子命令族同级还有mise bootstrap repos exec— 在选中的仓库中执行命令docs/cli/bootstrap/repos/exec.mdmise bootstrap repos status— 展示仓库检出状态docs/cli/bootstrap/repos/status.mdmise bootstrap repos update— 拉取最新变更docs/cli/bootstrap/repos/update.md从源码 src/cli/bootstrap.rs 的BootstrapReposApply结构体可以看到apply是BootstrapReposCommands枚举的四个变体之一实际逻辑委托给 src/cli/system/install.rs 中的apply_repos()。在顶层mise bootstrap的执行顺序中仓库检出位于[bootstrap.packages]之后、[dotfiles]之前src/cli/bootstrap.rs。这意味着一条典型的 bootstrap 流水线可以是先安装git等包再克隆 dotfiles 仓库最后从该检出目录应用 dotfiles——apply正是这条链路的中间环节。二、配置声明[bootstrap.repos]的完整语法仓库在mise.toml的[bootstrap.repos]表table中声明每个键是目标路径值是包含url与可选ref的 TOML 内联表[bootstrap.repos] ~/src/dotfiles { url gitgithub.com:jdx/dotfiles.git, ref main } ~/src/mise { url https://github.com/jdx/mise.git }字段语义字段必需取值说明url是任意合法 Git 远程地址克隆来源会被 trim 空白禁止为空、禁止以-开头防注入ref否分支名 / tag / 完整 commit SHA检出目标同样禁止为空或以-开头这些校验在源码 src/system/repos.rs 的RepoRequest::from_toml()中实现url缺失、为空或以-开头都会直接bail!ref为空或以-开头同样报错。对应测试见同文件 src/system/repos.rs如--upload-packsh、--detach这类会被 git 当作选项的恶意值均被拒绝。路径解析规则目标路径支持三种形式优先级与约束如下对应 src/system/repos.rs 与测试 src/system/repos.rs绝对路径按原样使用不与项目根拼接。~/开头路径展开为用户主目录同样不受项目根约束。注意裸~或~user/x会直接报错不会退化成字面量目录。相对路径相对声明该配置的文件的项目根解析且必须指向项目根内的一个目录不能是空字符串或.否则解析到项目根本身不能包含..、绝对段或PrefixWindows 盘符不允许逃逸项目根由于相对路径依赖项目根它只允许出现在项目配置中全局配置如~/.config/mise/config.toml使用相对路径会报错。实现细节解析时仅拼接Normal段./foobar会被规整为root/foobar避免.段泄漏进显示路径。三、apply命令参数详解命令签名与参数来自 docs/cli/bootstrap/repos/apply.mdmise bootstrap repos apply [FLAGS]Flag作用-n, --dry-run只打印将要执行的命令不实际执行-y, --yes跳过确认提示--skip-dirty跳过有本地改动的仓库而不是报错失败-h, --help打印帮助执行流程源码视角apply的实际执行链路位于 src/cli/system/install.rs 的通用mutate_repos()函数收集状态并行调用repos::status()计算每个仓库的状态status_one在 src/system/repos.rs。可选跳过 dirty传了--skip-dirty时状态为dirty的仓库被过滤并从列表移除同时打印repos: path has local changes, skipping警告否则 dirty 仓库会在 preflight 阶段直接使整个 apply 失败。preflight 校验调用preflight_statuses()dirty与conflict状态会中止整个命令——apply 不会在改写任何仓库之前放过冲突src/system/repos.rs。筛选目标apply只处理状态非current的仓库is_target |s| !s.state.is_current()current仓库打印repos: N repo(s) already current。确认与执行非 dry-run、非--yes且在交互终端user_attended_stderr时弹出repos: apply path?确认确认后调用apply_statuses()src/system/repos.rs逐个执行missing→ 克隆differs→ 更新。底层 git 操作克隆clone_reposrc/system/repos.rs先生成父目录再执行git clone若ref是分支/tag 且不是完整 SHA 或refs/前缀则追加--branch ref直接克隆到该引用src/system/repos.rs完整 SHA 或refs/引用则克隆后执行git checkout。所有 git 调用都带-c safe.directorypath与-c core.autocrlffalsesrc/system/repos.rs。更新update_reposrc/system/repos.rs执行git fetch --prune --tags origin→git checkout ref→ 若目标在本地或远端存在分支则git pull --ff-only origin ref。dry-run只通过print_git_command/shell_words::join打印将要运行的完整命令含-C path与safe.directory不执行任何写操作。四、安全语义什么情况下apply会拒绝操作与update相比apply是声明式收敛——它只把仓库带到配置声明的状态绝不进行强制重置。核心约束详见 docs/bootstrap/repos.md 的 Semantics 一节无隐式写入仓库只被显式的apply、update、exec或顶层mise bootstrap改变apply永远不会去 pull 一个未配置ref的已有仓库此时它被视作current原样保留。想要命令式拉取请用mise bootstrap repos update。无强制重置dirty 仓库、非空的非 git 目标路径、origin 不匹配的仓库都会失败而不是覆盖本地工作只有--skip-dirty能跳过 dirty 仓库conflict 仍然整体失败。缺省ref的仓库origin 匹配即视为currentmise 不会 fetch 或更新它。状态机StatesRepoState枚举定义于 src/system/repos.rsstatus命令输出、apply决策均依赖它状态含义apply 行为current仓库存在、origin 匹配、ref 匹配跳过already currentmissing目标路径不存在或为空目录克隆differs仓库干净但不在配置的 ref 上更新fetch checkout [ ff pull]dirty仓库有本地改动或未跟踪文件失败--skip-dirty时跳过conflict目标路径不是期望的 git 仓库非目录、非 git、空目录除外、origin 不匹配失败status_one()的判定顺序src/system/repos.rs路径不存在 →missing存在但不是目录 →conflict不是 git 仓库时为空目录 →missing否则 →conflictgit config --get remote.origin.url与配置 url 不匹配 →conflictorigin does not match configured urlgit status --porcelainv1非空 →dirty最后按ref匹配与否区分current与differs。ref的匹配通过ref_is_current()src/system/repos.rs对比当前分支/当前 SHA/本地refs/*与远端ls-remote结果完成。origin 匹配的传输无关比较这是apply判断“这是不是我声明的那个仓库”的关键逻辑src/system/repos.rs先做字面量/去尾斜杠/去.git后缀的常规归一化比较再提取repo identity仅ssh://、https://与 scp 风格githost:path三种形式会做传输无关比较——githost:path、ssh://githost/path、https://host/path被判定为同一仓库git用户与端口差异不计入 identityhost 转小写其余情况必须精确匹配http://、git://不安全传输不会被静默视为 https 配置、无用户的 sshgit 会解析为当前登录用户而非git、带 query 的 URL、本地路径、file://URL 都保持严格区分。换句话说如果你在配置里写https://host/path而本地仓库的 origin 是githost:pathapply认为是同一个仓库并允许收敛但若 origin 是http://host/path或ssh://loginhost/path会被判为conflict而拒绝操作。五、实战示例从声明到收敛1. 声明仓库# mise.toml [bootstrap.repos] ~/src/dotfiles { url gitgithub.com:jdx/dotfiles.git, ref main } ~/src/mise { url https://github.com/jdx/mise.git } # 未固定 ref vendor/plugins { url https://github.com/jdx/plugins.git, ref v1.2.3 } # 相对路径项目配置2. 查看将发生什么安全演练mise bootstrap repos status # 展示每个仓库的状态 mise bootstrap repos status --json # 机器可读输出-J mise bootstrap repos status --missing # 任一仓库非 current 则退出码 1适合 CI mise bootstrap repos apply --dry-run # 只打印将要执行的 git clone / fetch / checkout / pull3. 执行收敛mise bootstrap repos apply # 克隆 missing、收敛 differs交互确认 mise bootstrap repos apply --yes # 非交互执行 mise bootstrap repos apply --skip-dirty # 跳过有本地改动的仓库其余照常推荐流程先status观察再apply --dry-run核对命令最后正式apply。CI 中可用status --missing作为门禁。4. 完整 bootstrap 组合mise bootstrap packages apply --yes # 先安装 git 等包 mise bootstrap repos apply --yes # 再克隆/收敛 dotfiles 仓库 mise bootstrap dotfiles apply --yes # 最后应用 dotfiles其来源就在上面的检出中或直接执行顶层mise bootstrap它会按 packages → repos → dotfiles 的顺序一次性完成src/cli/bootstrap.rs。六、apply与update的取舍两者共享同一套状态机与mutate_repos框架差异仅在一个谓词src/cli/system/install.rsapply目标是!current的仓库即建立声明状态。未固定ref的已有匹配仓库视为 current保持原提交不动。update目标是!current或未固定 ref的仓库即命令式拉取——对无ref的仓库执行fetchpull --ff-only当前分支对 detached HEAD 的未固定仓库打印警告并跳过src/system/repos.rs。实践建议对应 docs/bootstrap/repos.md 的 Choose apply or update新机器初始化、想让仓库回到声明状态 →apply日常想同步最新代码不关心是否固定 ref→update两种命令都不会覆盖本地改动dirty 仓库默认整体失败需要时加--skip-dirty。七、前提与限制git 必须已安装且能对每个配置的 origin 完成认证ssh key、credential helper 等由你预先配置。相对路径只在项目配置中有效全局配置请用绝对路径或~/路径。仓库内容只通过显式 bootstrap 命令变更日常mise install等操作不会触碰[bootstrap.repos]的检出。http://、git://等不安全传输不会被宽松匹配配置与本地 origin 必须完全一致否则报conflict。通过把 dotfiles、工具源码等 Git 仓库声明进[bootstrap.repos]并用mise bootstrap repos apply收敛你可以获得一套可重复、可审计、拒绝覆盖本地工作的机器初始化流程——这正是 mise bootstrap 体系中“仓库检出”环节的完整用法。【免费下载链接】misedev tools, env vars, task runner项目地址: https://gitcode.com/GitHub_Trending/mi/mise创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考