-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Problem
When caching the paths suggested in the cargo guide Cargo Home, Caching the Cargo home in CI, git dependencies may end up getting rebuilt despite being present already in the cache.
This happens because git dependencies will get checked out from .cargo/git/db
into .cargo/git/checkouts
, which crucially will set the checkouted files' mtime
to the current time instead of the time they were commited. As a result, cargo will get the impression that the files have changed even though they haven't.
Steps
cargo new testproject
cd testproject
echo 'winapi = { git = "https://github.com/retep998/winapi-rs", branch = "0.3" }' >> Cargo.toml
cargo build
INVOKEDAT=$(stat -c %Y target/debug/build/winapi-*/invoked.timestamp)
BUILDRS_BEFORE=$(stat -c %Y ~/.cargo/git/checkouts/winapi-rs-*/*/build.rs)
rm -rf ~/.cargo/git/checkouts/winapi-rs-*
cargo build
BUILDRS_AFTER=$(stat -c %Y ~/.cargo/git/checkouts/winapi-rs-*/*/build.rs)
echo $BUILDRS_BEFORE
echo $BUILDRS_AFTER
echo "Rebuilding if BUILDRS_AFTER > $INVOKEDAT"
Notice winapi
gets rebuilt, despite not having changed. Notice also that winapi's build.rs file changed its mtime timestamp.
Possible Solution(s)
I see two possible solutions. Either this is considered "normal" and the documentation should be amended to recommend people to cache .cargo/git/checkouts
, or this is a bug and cargo should reset the files' mtime
after checking them out from git. Git does track the files' mtime, so it's certainly possible to do this, but it must be done manually as a simple git clone
/checkout/reset does not set the files' mtime.
Notes
Output of cargo version
: cargo 1.45.1 (f242df6 2020-07-22)