44use std:: env;
55use std:: fmt:: Display ;
66use std:: path:: { Path , PathBuf } ;
7- use std:: str:: { self , FromStr } ;
7+ use std:: str:: { self } ;
88use std:: sync:: LazyLock ;
99
1010use anyhow:: { Context , Result } ;
@@ -54,7 +54,7 @@ pub enum GitReference {
5454 /// From a named reference, like `refs/pull/493/head`.
5555 NamedRef ( String ) ,
5656 /// From a specific revision, using a full 40-character commit hash.
57- FullCommit ( String ) ,
57+ FullCommit ( GitOid ) ,
5858 /// The default branch of the repository, the reference named `HEAD`.
5959 DefaultBranch ,
6060}
@@ -87,7 +87,7 @@ impl GitReference {
8787 Self :: Branch ( rev) => Some ( rev) ,
8888 Self :: BranchOrTag ( rev) => Some ( rev) ,
8989 Self :: BranchOrTagOrCommit ( rev) => Some ( rev) ,
90- Self :: FullCommit ( rev) => Some ( rev) ,
90+ Self :: FullCommit ( rev) => Some ( rev. as_str ( ) ) ,
9191 Self :: NamedRef ( rev) => Some ( rev) ,
9292 Self :: DefaultBranch => None ,
9393 }
@@ -100,7 +100,7 @@ impl GitReference {
100100 Self :: Branch ( rev) => rev,
101101 Self :: BranchOrTag ( rev) => rev,
102102 Self :: BranchOrTagOrCommit ( rev) => rev,
103- Self :: FullCommit ( rev) => rev,
103+ Self :: FullCommit ( rev) => rev. as_str ( ) ,
104104 Self :: NamedRef ( rev) => rev,
105105 Self :: DefaultBranch => "HEAD" ,
106106 }
@@ -122,7 +122,7 @@ impl GitReference {
122122 /// Returns the precise [`GitOid`] of this reference, if it's a full commit.
123123 pub ( crate ) fn as_sha ( & self ) -> Option < GitOid > {
124124 if let Self :: FullCommit ( rev) = self {
125- Some ( GitOid :: from_str ( rev) . expect ( "Full commit should be exactly 40 characters" ) )
125+ Some ( * rev)
126126 } else {
127127 None
128128 }
@@ -241,7 +241,7 @@ impl GitRemote {
241241 locked_rev : Option < GitOid > ,
242242 client : & ClientWithMiddleware ,
243243 ) -> Result < ( GitDatabase , GitOid ) > {
244- let locked_ref = locked_rev. map ( |oid| GitReference :: FullCommit ( oid . to_string ( ) ) ) ;
244+ let locked_ref = locked_rev. map ( GitReference :: FullCommit ) ;
245245 let reference = locked_ref. as_ref ( ) . unwrap_or ( reference) ;
246246 let enable_lfs_fetch = env:: var ( EnvVars :: UV_GIT_LFS ) . is_ok ( ) ;
247247
@@ -362,8 +362,11 @@ impl GitReference {
362362 // We'll be using the HEAD commit.
363363 Self :: DefaultBranch => repo. rev_parse ( "refs/remotes/origin/HEAD" ) ,
364364
365+ // Resolve a named reference.
366+ Self :: NamedRef ( s) => repo. rev_parse ( & format ! ( "{s}^0" ) ) ,
367+
365368 // Resolve a direct commit reference.
366- Self :: FullCommit ( s) | Self :: NamedRef ( s ) => repo. rev_parse ( & format ! ( "{s}^0" ) ) ,
369+ Self :: FullCommit ( s) => repo. rev_parse ( & format ! ( "{s}^0" ) ) ,
367370 } ;
368371
369372 result. with_context ( || anyhow:: format_err!( "failed to find {refkind} `{self}`" ) )
@@ -543,17 +546,7 @@ pub(crate) fn fetch(
543546 }
544547
545548 GitReference :: FullCommit ( rev) => {
546- if let Some ( oid_to_fetch) = oid_to_fetch {
547- refspecs. push ( format ! ( "+{oid_to_fetch}:refs/commit/{oid_to_fetch}" ) ) ;
548- } else {
549- // There is a specific commit to fetch and we will do so in shallow-mode only
550- // to not disturb the previous logic.
551- // Note that with typical settings for shallowing, we will just fetch a single `rev`
552- // as single commit.
553- // The reason we write to `refs/remotes/origin/HEAD` is that it's of special significance
554- // when during `GitReference::resolve()`, but otherwise it shouldn't matter.
555- refspecs. push ( format ! ( "+{rev}:refs/remotes/origin/HEAD" ) ) ;
556- }
549+ refspecs. push ( format ! ( "+{rev}:refs/commit/{rev}" ) ) ;
557550 }
558551 }
559552
@@ -753,16 +746,15 @@ fn github_fast_path(
753746 GitReference :: FullCommit ( rev) => {
754747 debug ! ( "Skipping GitHub fast path; full commit hash provided: {rev}" ) ;
755748
756- let rev = GitOid :: from_str ( rev) ?;
757749 if let Some ( ref local_object) = local_object {
758- if rev == * local_object {
750+ if rev == local_object {
759751 return Ok ( FastPathRev :: UpToDate ) ;
760752 }
761753 }
762754
763755 // If we know the reference is a full commit hash, we can just return it without
764756 // querying GitHub.
765- return Ok ( FastPathRev :: NeedsFetch ( rev) ) ;
757+ return Ok ( FastPathRev :: NeedsFetch ( * rev) ) ;
766758 }
767759 } ;
768760
0 commit comments