Fix reuse of Git commits in lockfile (#5908)

## Summary

See: https://github.com/astral-sh/uv/pull/5886/files#r1709430408
This commit is contained in:
Charlie Marsh
2024-08-08 09:01:59 -04:00
committed by GitHub
parent 61b0a88107
commit 9f32c41552
3 changed files with 47 additions and 6 deletions
+17 -4
View File
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::path::PathBuf;
use std::sync::Arc;
@@ -47,6 +48,18 @@ impl GitResolver {
) -> Result<Fetch, GitResolverError> {
debug!("Fetching source distribution from Git: {url}");
let reference = RepositoryReference::from(url);
// If we know the precise commit already, reuse it, to ensure that all fetches within a
// single process are consistent.
let url = {
if let Some(precise) = self.get(&reference) {
Cow::Owned(url.clone().with_precise(*precise))
} else {
Cow::Borrowed(url)
}
};
// Avoid races between different processes, too.
let lock_dir = cache.join("locks");
fs::create_dir_all(&lock_dir).await?;
@@ -58,17 +71,17 @@ impl GitResolver {
// Fetch the Git repository.
let source = if let Some(reporter) = reporter {
GitSource::new(url.clone(), client, cache).with_reporter(reporter)
GitSource::new(url.as_ref().clone(), client, cache).with_reporter(reporter)
} else {
GitSource::new(url.clone(), client, cache)
GitSource::new(url.as_ref().clone(), client, cache)
};
let fetch = tokio::task::spawn_blocking(move || source.fetch())
.await?
.map_err(GitResolverError::Git)?;
// Insert the resolved URL into the in-memory cache.
// Insert the resolved URL into the in-memory cache. This ensures that subsequent fetches
// resolve to the same precise commit.
if let Some(precise) = fetch.git().precise() {
let reference = RepositoryReference::from(url);
self.insert(reference, precise);
}
+1
View File
@@ -387,6 +387,7 @@ async fn do_lock(
// Populate the Git resolver.
for ResolvedRepositoryReference { reference, sha } in git {
debug!("Inserting Git reference into resolver: `{reference:?}` at `{sha}`");
state.git.insert(reference, sha);
}
+29 -2
View File
@@ -2385,9 +2385,36 @@ fn lock_git_sha() -> Result<()> {
// Rewrite the lockfile, as if it were locked against `main`.
let lock = lock.replace("rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979", "rev=main");
insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
lock, @r###"
version = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25 00:00:00 UTC"
[[distribution]]
name = "project"
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "uv-public-pypackage" },
]
[[distribution]]
name = "uv-public-pypackage"
version = "0.1.0"
source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=main#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" }
"###
);
});
fs_err::write(context.temp_dir.join("uv.lock"), lock)?;
// Lock `anyio` against `main`.
// Lock against `main`.
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
@@ -2436,7 +2463,7 @@ fn lock_git_sha() -> Result<()> {
[[distribution]]
name = "uv-public-pypackage"
version = "0.1.0"
source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=main#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" }
source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=main#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" }
"###
);
});