@@ -6,6 +6,7 @@ use crate::core::global_cache_tracker;
66use crate :: core:: { Dependency , Package , PackageId } ;
77use crate :: sources:: IndexSummary ;
88use crate :: sources:: RecursivePathSource ;
9+ use crate :: sources:: git:: utils:: GitDatabase ;
910use crate :: sources:: git:: utils:: GitRemote ;
1011use crate :: sources:: git:: utils:: rev_to_oid;
1112use crate :: sources:: source:: MaybePackage ;
@@ -155,6 +156,63 @@ impl<'gctx> GitSource<'gctx> {
155156 } ) ;
156157 Ok ( ( ) )
157158 }
159+
160+ pub ( crate ) fn update_db ( & self ) -> CargoResult < ( GitDatabase , git2:: Oid ) > {
161+ let db_path = self . gctx . git_db_path ( ) . join ( & self . ident ) ;
162+ let db_path = db_path. into_path_unlocked ( ) ;
163+
164+ let db = self . remote . db_at ( & db_path) . ok ( ) ;
165+
166+ let ( db, actual_rev) = match ( & self . locked_rev , db) {
167+ // If we have a locked revision, and we have a preexisting database
168+ // which has that revision, then no update needs to happen.
169+ ( Revision :: Locked ( oid) , Some ( db) ) if db. contains ( * oid) => ( db, * oid) ,
170+
171+ // If we're in offline mode, we're not locked, and we have a
172+ // database, then try to resolve our reference with the preexisting
173+ // repository.
174+ ( Revision :: Deferred ( git_ref) , Some ( db) ) if !self . gctx . network_allowed ( ) => {
175+ let offline_flag = self
176+ . gctx
177+ . offline_flag ( )
178+ . expect ( "always present when `!network_allowed`" ) ;
179+ let rev = db. resolve ( & git_ref) . with_context ( || {
180+ format ! (
181+ "failed to lookup reference in preexisting repository, and \
182+ can't check for updates in offline mode ({offline_flag})"
183+ )
184+ } ) ?;
185+ ( db, rev)
186+ }
187+
188+ // ... otherwise we use this state to update the git database. Note
189+ // that we still check for being offline here, for example in the
190+ // situation that we have a locked revision but the database
191+ // doesn't have it.
192+ ( locked_rev, db) => {
193+ if let Some ( offline_flag) = self . gctx . offline_flag ( ) {
194+ anyhow:: bail!(
195+ "can't checkout from '{}': you are in the offline mode ({offline_flag})" ,
196+ self . remote. url( )
197+ ) ;
198+ }
199+
200+ if !self . quiet {
201+ self . gctx . shell ( ) . status (
202+ "Updating" ,
203+ format ! ( "git repository `{}`" , self . remote. url( ) ) ,
204+ ) ?;
205+ }
206+
207+ trace ! ( "updating git source `{:?}`" , self . remote) ;
208+
209+ let locked_rev = locked_rev. clone ( ) . into ( ) ;
210+ self . remote . checkout ( & db_path, db, & locked_rev, self . gctx ) ?
211+ }
212+ } ;
213+
214+ Ok ( ( db, actual_rev) )
215+ }
158216}
159217
160218/// Indicates a [Git revision] that might be locked or deferred to be resolved.
@@ -286,58 +344,7 @@ impl<'gctx> Source for GitSource<'gctx> {
286344 // exists.
287345 exclude_from_backups_and_indexing ( & git_path) ;
288346
289- let db_path = self . gctx . git_db_path ( ) . join ( & self . ident ) ;
290- let db_path = db_path. into_path_unlocked ( ) ;
291-
292- let db = self . remote . db_at ( & db_path) . ok ( ) ;
293-
294- let ( db, actual_rev) = match ( & self . locked_rev , db) {
295- // If we have a locked revision, and we have a preexisting database
296- // which has that revision, then no update needs to happen.
297- ( Revision :: Locked ( oid) , Some ( db) ) if db. contains ( * oid) => ( db, * oid) ,
298-
299- // If we're in offline mode, we're not locked, and we have a
300- // database, then try to resolve our reference with the preexisting
301- // repository.
302- ( Revision :: Deferred ( git_ref) , Some ( db) ) if !self . gctx . network_allowed ( ) => {
303- let offline_flag = self
304- . gctx
305- . offline_flag ( )
306- . expect ( "always present when `!network_allowed`" ) ;
307- let rev = db. resolve ( & git_ref) . with_context ( || {
308- format ! (
309- "failed to lookup reference in preexisting repository, and \
310- can't check for updates in offline mode ({offline_flag})"
311- )
312- } ) ?;
313- ( db, rev)
314- }
315-
316- // ... otherwise we use this state to update the git database. Note
317- // that we still check for being offline here, for example in the
318- // situation that we have a locked revision but the database
319- // doesn't have it.
320- ( locked_rev, db) => {
321- if let Some ( offline_flag) = self . gctx . offline_flag ( ) {
322- anyhow:: bail!(
323- "can't checkout from '{}': you are in the offline mode ({offline_flag})" ,
324- self . remote. url( )
325- ) ;
326- }
327-
328- if !self . quiet {
329- self . gctx . shell ( ) . status (
330- "Updating" ,
331- format ! ( "git repository `{}`" , self . remote. url( ) ) ,
332- ) ?;
333- }
334-
335- trace ! ( "updating git source `{:?}`" , self . remote) ;
336-
337- let locked_rev = locked_rev. clone ( ) . into ( ) ;
338- self . remote . checkout ( & db_path, db, & locked_rev, self . gctx ) ?
339- }
340- } ;
347+ let ( db, actual_rev) = self . update_db ( ) ?;
341348
342349 // Don’t use the full hash, in order to contribute less to reaching the
343350 // path length limit on Windows. See
0 commit comments