rust - 将临时 git 依赖项修补到特定版本

标签 rust dependency-management rust-cargo

我依赖于 crates ab,我将 b 修补为对 ref 的 git 依赖 foo:

# Cargo.toml of my crate
[dependencies]
a = "1.0.0"
b = "1.0.0"

[patch.crates-io]
b = { git = "https://github.com/user/example", rev = "foo" }

a 也依赖于 b 作为 git 依赖项,但不依赖于特定的 ref:

# Cargo.toml of a
[dependencies]
b = { git = "https://github.com/user/example" }

我想强制 a 像我一样对 b 使用相同的 ref,我想我可以这样做:

# The ideal Cargo.toml of my crate
[dependencies]
a = "1.0.0"
b = "1.0.0"

# patch local dependency
[patch.crates-io]
b = { git = "https://github.com/user/example", rev = "foo" }

# patch transient dependency
[patch.'https://github.com/user/example']
b = { git = "https://github.com/user/example", rev = "foo" }

但这不起作用,因为我正在修补的源仍然指向相同的源,只是在不同的 rev 中:

error: failed to resolve patches for `https://github.com/user/example`

Caused by:
  patch for `b` in `https://github.com/user/example` points to the same source, but patches must point to different sources
[Finished running. Exit status: 101]

到目前为止,我的解决方法是 fork b 并像这样打补丁:

# Cargo.toml of my crate using a work around
[dependencies]
a = "1.0.0"
b = "1.0.0"

[patch.crates-io]
b = { git = "https://github.com/me/example", rev = "foo" } # Using my fork

[patch.'https://github.com/user/example']
b = { git = "https://github.com/me/example", rev = "foo" } # Using my fork

这行得通,但 fork 基本上没用。有更好的方法吗?


我试过了 this hack , 但它也不起作用,因为它只是忽略了 rev。整个 GitHub 问题让我看起来目前不支持我正在尝试的东西,但很难说,因为它不是完全相同的功能。

最佳答案

根据 this GitHub issue ,目前不支持此功能,因为 git 依赖项专门通过 URL 进行区分,而不是修订。某些 URL 被视为相同,例如 .git ending always being stripped ,但 cargo 仍然只是比较 URL 而没有其他。
然而,我们可以利用这个“特性”来发挥我们的优势:添加 ?ref=foo到 URL 的末尾将使它看起来像一个新的来源:

# Fixed Cargo.toml
[dependencies]
a = "1.0.0"
b = "1.0.0"

# patch local dependency
[patch.crates-io]
b = { git = "https://github.com/user/example?rev=foo" }

# patch transient dependency
[patch.'https://github.com/user/example']
b = { git = "https://github.com/user/example?rev=foo" }

小心在两个 补丁中使用 URL hack,否则你会创建一个损坏的 Cargo.lock有两个 b 的定义:

# Corrupt Cargo.toml
[dependencies]
a = "1.0.0"
b = "1.0.0"

# patch local dependency
[patch.crates-io]
b = { git = "https://github.com/user/example", rev = "foo" } # mistake!

# patch transient dependency
[patch.'https://github.com/user/example']
b = { git = "https://github.com/user/example?rev=foo" }

虽然我没有测试它,但这种方法原则上也应该通过附加 /tree/<branch> 来处理分支上的补丁。到 URL。

关于rust - 将临时 git 依赖项修补到特定版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72240671/

相关文章:

version-control - 一次开发多个 npm 模块的方法(具有交叉依赖)

Maven 测试依赖关系从 uberjar 中删除传递编译依赖关系

python - Python 3 中的模块依赖关系图

rust - 如何导入同一个 crate 的多个版本?

module - 如何使用新的本地模块?

rust - 如果Rust项目已更新,请重新运行规则

parsing - 使用 lalrpop 解析 rust 中由 "引用的字符串

string - 为什么我需要 to_string 函数的引用?

linker - Cargo 创建空的 ELF 文件

rust - 交叉编译 [no_std] 代码 - 未找到 libcore 和 compiler_builtins