我依赖于 crate ab,我在ref foo上将b修补为git依赖:

# 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和我一样用refb,我想我可以这样做:

# 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]

到目前为止,我的解决方法是Forking 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的整个问题让我觉得我正在try 的功能目前不受支持,但很难说,因为它不是完全相同的功能.

推荐答案

Per this GitHub issue, this feature is currently not supported, since git dependencies are differentiated exclusively via URL, not revision. Some URLs are treated as the same, e.g. the .git ending always being stripped, but cargo is still just comparing URLs and nothing else.
We can however use this "feature" to our advantage: Adding a ?ref=foo to the end of the URL will make it look like a new source:

# 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" }

小心在both补丁中使用URL攻击,否则你将创建一个包含两个b定义的损坏的Cargo.lock:

# 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" }

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

Rust相关问答推荐

使用Rust s serde_json对混合数据类型进行优化'

限制未使用的泛型导致编译错误

"value is never read警告似乎不正确.我应该忽略它吗?

防止cargo test 中的竞争条件

如何使用Actix Web for Rust高效地为大文件服务

如何将实现多个特征的 struct 传递给接受这些特征为&;mut?

为什么RefCell没有与常规引用相同的作用域?

在 Rust 中用问号传播错误时对类型转换的困惑?

如何在 Rust 中编写一个通用方法,它可以接受任何可以转换为另一个值的值?

我如何取消转义,在 Rust 中多次转义的字符串?

Rust 中的自动取消引用是如何工作的?

在给定 Rust 谓词的情况下,将 Some 转换为 None 的惯用方法是什么?

如何在 Emacs Elisp 中获得类似格式化的 LSP?

为什么不可变特征的实现可以是可变的?

仅当函数写为闭包时才会出现生命周期错误

如何将参数传递给Rust 的线程?

Rust 引用元组和引用元组

`map` 调用在这里有什么用吗?

带有库+多个二进制文件的Cargo 项目,二进制文件由多个文件组成?

为什么我不能为 Display+Debug 的泛型类型实现 std::error::Error 但有一个不是泛型参数的类型?