@@ -188,37 +188,42 @@ public class RepositoryManager: Cancellable {
188188 // sync func and roll the logic into the async version above
189189 private func lookup(
190190 package : PackageIdentity ,
191- repository: RepositorySpecifier ,
191+ repository repositorySpecifier : RepositorySpecifier ,
192192 updateStrategy: RepositoryUpdateStrategy ,
193193 observabilityScope: ObservabilityScope ,
194194 delegateQueue: DispatchQueue
195195 ) throws -> RepositoryHandle {
196- let relativePath = try repository . storagePath ( )
196+ let relativePath = try repositorySpecifier . storagePath ( )
197197 let repositoryPath = self . path. appending ( relativePath)
198- let handle = RepositoryHandle ( manager: self , repository: repository , subpath: relativePath)
198+ let handle = RepositoryHandle ( manager: self , repository: repositorySpecifier , subpath: relativePath)
199199
200200 // check if a repository already exists
201201 // errors when trying to check if a repository already exists are legitimate
202202 // and recoverable, and as such can be ignored
203- if ( try ? self . provider. repositoryExists ( at: repositoryPath) ) ?? false {
203+ quick: if ( try ? self . provider. repositoryExists ( at: repositoryPath) ) ?? false {
204204 let repository = try handle. open ( )
205+
206+ guard ( ( try ? self . provider. isValidDirectory ( repositoryPath, for: repositorySpecifier) ) ?? false ) else {
207+ observabilityScope. emit ( warning: " \( repositoryPath) is not valid git repository for ' \( repositorySpecifier. location) ', will fetch again. " )
208+ break quick
209+ }
210+
205211 // Update the repository if needed
206212 if self . fetchRequired ( repository: repository, updateStrategy: updateStrategy) {
207213 let start = DispatchTime . now ( )
208-
214+
209215 delegateQueue. async {
210216 self . delegate? . willUpdate ( package : package , repository: handle. repository)
211217 }
212-
218+
213219 try repository. fetch ( )
214220 let duration = start. distance ( to: . now( ) )
215221 delegateQueue. async {
216222 self . delegate? . didUpdate ( package : package , repository: handle. repository, duration: duration)
217223 }
218- return handle
219- } else if try self . provider. isValidDirectory ( repositoryPath) {
220- return handle
221224 }
225+
226+ return handle
222227 }
223228
224229 // inform delegate that we are starting to fetch
@@ -334,7 +339,7 @@ public class RepositoryManager: Cancellable {
334339 }
335340 } catch {
336341 // If we are offline and have a valid cached repository, use the cache anyway.
337- if try isOffline ( error) && self . provider. isValidDirectory ( cachedRepositoryPath) {
342+ if try isOffline ( error) && self . provider. isValidDirectory ( cachedRepositoryPath, for : handle . repository ) {
338343 // For the first offline use in the lifetime of this repository manager, emit a warning.
339344 if self . emitNoConnectivityWarning. get ( default: false ) {
340345 self . emitNoConnectivityWarning. put ( false )
@@ -426,6 +431,10 @@ public class RepositoryManager: Cancellable {
426431 try self . provider. isValidDirectory ( directory)
427432 }
428433
434+ public func isValidDirectory( _ directory: AbsolutePath , for repository: RepositorySpecifier ) throws -> Bool {
435+ try self . provider. isValidDirectory ( directory, for: repository)
436+ }
437+
429438 /// Reset the repository manager.
430439 ///
431440 /// Note: This also removes the cloned repositories from the disk.
0 commit comments