Skip to content

Allow replaced git sources to not include the git history #16141

@nmattia

Description

@nmattia

Problem

The Source Replacement mechanism allows for sandboxed build systems to download crates ahead of times and replace remote crates with local downloads at build time.

There is however an issue with git sources that include workspaces (virtual manifests). Such a git source can only be replaced with another (local) git source as (as far as I can tell) only git sources are searched recursively (for workspace members). Since some build systems only support downloading archives (tar.gz, zip, etc) without the actual .git history, the git sources cannot be replaced:

[source]

[source.naersk-git-rand]
git = "file:///nix/store/downloaded-ahead-of-time/rand"

[source."foo"]
git = "git+https://github.com/rust-random/rand"
rev="703452450770d4b2bb0b117dfc83aea5ba61ec60"

replace-with = "naersk-git-rand"
cargo check      
   Updating git repository `file:///nix/store/downloaded-ahead-of-time/rand`
error: failed to get `rand` as a dependency of package `git-dep v0.1.0 (/Users/nicolas/naersk/test/fast/git-dep/fixtures)`

Caused by:
 failed to load source for dependency `rand`

Caused by:
 Unable to update https://github.com/rust-random/rand?rev=703452450770d4b2bb0b117dfc83aea5ba61ec60#70345245

Caused by:
 failed to update replaced source https://github.com/rust-random/rand?rev=703452450770d4b2bb0b117dfc83aea5ba61ec60#70345245

Caused by:
 revspec '703452450770d4b2bb0b117dfc83aea5ba61ec60' not found; class=Reference (4); code=NotFound (-3)

Here are some Nix projects that run into the issue (one with a workaround):

I haven't looked at the cargo internals in a while; hope I'm not missing something obvious!

Proposed Solution

If other source types could be searched recursively, or if the rev could also be replaced, replacing git sources would be much easier.

Something like this would allow the build system to recreate a git history and use this:

[source.naersk-git]
git = "file:///nix/store/..."
rev = "<the-new-rev>"

[source."foo"]

git = "https://github.com/rust-random/rand"
rev="703452450770d4b2bb0b117dfc83aea5ba61ec60"

replace-with = "naersk-git"

Alternatively, existing source types like directory could support recursively looking for packages.

Thanks!

Notes

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-directory-sourceArea: directory sources (vendoring)A-source-replacementArea: [source] replacementC-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`S-triageStatus: This issue is waiting on initial triage.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions