Cargo vendor 中 --precise 返回成功却没降版,检查实际锁定版本
Cargo 1.99.0 使用目录源且同时保留多个版本时,--precise 可返回成功而锁文件仍选较新版本。用实际锁文件验收,并在清单约束或受控依赖准备阶段固定所需版本。
cargo update --offline -p itoa --precise 1.0.0 返回成功,Cargo.lock 却仍选中较新的 1.0.x。若 crates.io 已被替换为本地目录源,而且 vendor 中同时保留这两个版本,应直接比较锁文件,不能把退出码零当成降版完成。
Cargo 1.99.0 的这个场景使用普通稳定版本;同一版本请求走 registry source 时可以降版,走 directory source 时却保留满足原清单范围的较新候选。它与预发布版本不满足依赖要求、目标包根本没被 vendoring,是不同的检查路径。
目录里有旧包,不等于解析器选中了它
先确认有效配置确实把 crates.io 替换为带 .cargo-checksum.json 的 directory source,且目标旧版本完整存在。不要把目录源与带索引的 local registry 混在一起,也不要只检查 vendor 的文件夹名称。
再核对清单的版本范围、锁文件中的包版本与 source,以及是否同时存在多个同名版本。itoa = "1" 允许多个 1.x 候选,--precise 1.0.0 则表达这次更新希望选定的版本;两者的作用不同。请求的旧版本仍必须满足依赖图中的相关要求。
正式 Cargo 0.100.0 源码对应提交 5f94df478,也是 Rust 1.99.1 发布通道所带的 Cargo 构建。其 registry 查询分支会读取 precise 版本并收紧查询要求;directory 查询分支则按依赖原有要求匹配候选,没有同样的处理。因此,这个目录源场景需要核对实际选择结果,不能据普通 registry 的行为推断它已生效。Rust 1.99.1 所带的这一构建仍有该差异;更换工具链后,也要核对锁文件的实际变化。
在依赖约束或锁文件生成阶段控制版本
如果应用确实要长期固定直接依赖为 1.0.0,可以评估在自己的 Cargo.toml 中使用精确要求:
[dependencies]
itoa = "=1.0.0"
这会改变项目允许的依赖版本,不是无副作用的查询。示例只适用于项目可控制的直接依赖,不能把它机械加到任意传递依赖上;其他依赖若仍需要较新版本,图中也可能同时保留两份 itoa。保留原清单和锁文件,审查更新后的完整差异。
另一个处理入口是在允许访问原 registry 的受控依赖准备阶段,按审定版本生成锁文件,再据这份锁文件重新生成 vendor 内容和替换配置。切回离线构建后,应使用同一份清单、锁文件和完整目录源验收。这个流程需要项目允许的来源、网络与构建脚本执行条件,不能在受限环境中临时绕过来源策略。
不要手改 .cargo-checksum.json,也不要直接删除 vendor 中较新的包来迫使解析。它可能仍被另一条依赖路径需要;手改 Cargo.lock 中的版本而不维护来源和校验内容,也不能形成可重复的依赖状态。
验收逐项查看目标包的锁定版本、来源和重复版本路径,再用原项目的锁定离线构建与行为检查确认实际使用的代码。若命令成功但锁文件没有预期变化,应继续按未完成处理,保留 Cargo 版本、来源替换配置和更新前后锁文件供比较。


