我依赖于板条箱a
和b
,在那里我修补了b
到一个git依赖于ref
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]
到目前为止,我的解决方案是分叉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
这是可行的,但分叉实际上是无用的。有更好的方法吗?
我试过这个hack,但它不工作,因为它只是忽略了rev
。整个GitHub问题使它看起来像我正在尝试的目前不支持,但很难说,因为它不是完全相同的功能。
根据这个GitHub问题,这个功能目前不支持,因为git依赖项是通过URL而不是修订来区分的。一些url被视为相同的,例如.git
结尾总是被剥离,但货物仍然只是比较url,而不是其他。
我们可以使用这个"特性"。对我们有利:在URL的末尾添加?ref=foo
将使它看起来像一个新的源代码:
# 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来处理分支上的补丁。