@@ -105,24 +105,29 @@ pub fn ensure_bare_repo(path: &Path) -> Result<Repository> {
105105 }
106106}
107107
108- /// Try to resolve `commitish` locally. If it doesn't exist, try to fetch it from `upstream_url`.
108+ /// Try to resolve and fetch `commitish` from `upstream_url`.
109+ ///
110+ /// As an optimization, it can skip fetching if `commitish` is a literal commit ID that exists locally.
109111///
110112/// Returns the resolved commit ID.
111113#[ tracing:: instrument( skip( repo) ) ]
112- pub fn resolve_commitish_or_fetch (
114+ pub fn resolve_and_fetch_commitish (
113115 repo : & Repository ,
114116 commitish : & str ,
115117 upstream_url : & str ,
116118) -> Result < Oid > {
117- let commit = match repo. revparse_single ( commitish) {
119+ let oid = Oid :: from_str ( commitish) ;
120+ let commitish_is_oid = oid. is_ok ( ) ;
121+ let local_commit = oid. and_then ( |oid| repo. find_commit ( oid) ) ;
122+ let commit = match local_commit {
118123 Ok ( commit_obj) => {
119- tracing:: info!( "base commit exists, reusing" ) ;
124+ tracing:: info!( "literal commit exists locally , reusing" ) ;
120125 Ok ( commit_obj)
121126 }
122- Err ( err) if err. code ( ) == git2:: ErrorCode :: NotFound => {
127+ Err ( err) if !commitish_is_oid || err. code ( ) == git2:: ErrorCode :: NotFound => {
123128 tracing:: info!(
124129 error = & err as & dyn std:: error:: Error ,
125- "base commit not found, fetching from upstream"
130+ "base commit not found locally , fetching from upstream"
126131 ) ;
127132 repo. remote_anonymous ( upstream_url)
128133 . context ( CreateRemoteSnafu {
@@ -147,17 +152,15 @@ pub fn resolve_commitish_or_fetch(
147152 tracing:: info!( "fetched base commit" ) ;
148153 // FETCH_HEAD is written by Remote::fetch to be the last reference fetched
149154 repo. revparse_single ( "FETCH_HEAD" )
155+ . and_then ( |obj| obj. peel_to_commit ( ) )
150156 }
151157 Err ( err) => Err ( err) ,
152158 }
153159 . context ( FindCommitSnafu {
154160 repo,
155161 commit : commitish,
156162 } ) ?;
157- Ok ( commit
158- . peel_to_commit ( )
159- . context ( FindCommitSnafu { repo, commit } ) ?
160- . id ( ) )
163+ Ok ( commit. id ( ) )
161164}
162165
163166/// Ensure that the worktree at `worktree_root` exists and is checked out at `branch`.
0 commit comments