Respect resolved Git SHAs in uv lock (#3956)

## Summary

This PR ensures that if a lockfile already contains a resolved reference
(e.g., you locked with `main` previously, and it locked to a specific
commit), and you run `uv lock`, we use the same SHA, even if it's not
the latest SHA for that tag. This avoids upgrading Git dependencies
without `--upgrade`.

Closes #3920.
This commit is contained in:
Charlie Marsh 2024-06-01 08:40:11 -04:00 committed by GitHub
parent b7d77c04cc
commit c04a95e037
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 251 additions and 66 deletions

View file

@ -2,7 +2,9 @@ use std::str::FromStr;
use url::Url;
pub use crate::git::GitReference;
pub use crate::resolver::{GitResolver, GitResolverError, RepositoryReference};
pub use crate::resolver::{
GitResolver, GitResolverError, RepositoryReference, ResolvedRepositoryReference,
};
pub use crate::sha::{GitOid, GitSha, OidParseError};
pub use crate::source::{Fetch, GitSource, Reporter};

View file

@ -27,6 +27,15 @@ pub enum GitResolverError {
pub struct GitResolver(Arc<DashMap<RepositoryReference, GitSha>>);
impl GitResolver {
/// Initialize a [`GitResolver`] with a set of resolved references.
pub fn from_refs(refs: Vec<ResolvedRepositoryReference>) -> Self {
Self(Arc::new(
refs.into_iter()
.map(|ResolvedRepositoryReference { reference, sha }| (reference, sha))
.collect(),
))
}
/// Returns the [`GitSha`] for the given [`RepositoryReference`], if it exists.
pub fn get(&self, reference: &RepositoryReference) -> Option<Ref<RepositoryReference, GitSha>> {
self.0.get(reference)
@ -136,11 +145,20 @@ impl GitResolver {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ResolvedRepositoryReference {
/// An abstract reference to a Git repository, including the URL and the commit (e.g., a branch,
/// tag, or revision).
pub reference: RepositoryReference,
/// The precise commit SHA of the reference.
pub sha: GitSha,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RepositoryReference {
/// The URL of the Git repository, with any query parameters and fragments removed.
pub url: RepositoryUrl,
/// The reference to the commit to use, which could be a branch, tag or revision.
/// The reference to the commit to use, which could be a branch, tag, or revision.
pub reference: GitReference,
}