@@ -3309,8 +3309,13 @@ extension Workspace {
33093309 observabilityScope: ObservabilityScope
33103310 ) throws -> AbsolutePath {
33113311 let repository = try package . makeRepositorySpecifier ( )
3312- // first fetch the repository.
3313- let checkoutPath = try self . fetchRepository ( package : package , observabilityScope: observabilityScope)
3312+
3313+ // first fetch the repository
3314+ let checkoutPath = try self . fetchRepository (
3315+ package : package ,
3316+ at: checkoutState. revision,
3317+ observabilityScope: observabilityScope
3318+ )
33143319
33153320 // Check out the given revision.
33163321 let workingCopy = try self . repositoryManager. openWorkingCopy ( at: checkoutPath)
@@ -3378,37 +3383,40 @@ extension Workspace {
33783383 ///
33793384 /// - Returns: The path of the local repository.
33803385 /// - Throws: If the operation could not be satisfied.
3381- private func fetchRepository( package : PackageReference , observabilityScope: ObservabilityScope ) throws -> AbsolutePath {
3386+ private func fetchRepository(
3387+ package : PackageReference ,
3388+ at revision: Revision ,
3389+ observabilityScope: ObservabilityScope
3390+ ) throws -> AbsolutePath {
3391+ let repository = try package . makeRepositorySpecifier ( )
3392+
33823393 // If we already have it, fetch to update the repo from its remote.
33833394 // also compare the location as it may have changed
33843395 if let dependency = self . state. dependencies [ comparingLocation: package ] {
3385- let path = self . location. repositoriesCheckoutSubdirectory ( for: dependency)
3396+ let checkoutPath = self . location. repositoriesCheckoutSubdirectory ( for: dependency)
33863397
3387- // Make sure the directory is not missing (we will have to clone again
3388- // if not) .
3389- fetch: if self . fileSystem. isDirectory ( path ) {
3398+ // Make sure the directory is not missing (we will have to clone again if not).
3399+ // This can become invalid if the build directory is moved .
3400+ fetch: if self . fileSystem. isDirectory ( checkoutPath ) {
33903401 // Fetch the checkout in case there are updates available.
3391- let workingCopy = try self . repositoryManager. openWorkingCopy ( at: path )
3402+ let workingCopy = try self . repositoryManager. openWorkingCopy ( at: checkoutPath )
33923403
33933404 // Ensure that the alternative object store is still valid.
3394- //
3395- // This can become invalid if the build directory is moved.
3396- guard workingCopy. isAlternateObjectStoreValid ( ) else {
3405+ guard try self . repositoryManager. isValidWorkingCopy ( workingCopy, for: repository) else {
3406+ observabilityScope. emit ( debug: " working copy at ' \( checkoutPath) ' does not align with expected local path of ' \( repository) ' " )
33973407 break fetch
33983408 }
33993409
3400- // The fetch operation may update contents of the checkout, so
34013410 // we need do mutable-immutable dance.
3402- try self . fileSystem. chmod ( . userWritable, path: path , options: [ . recursive, . onlyFiles] )
3411+ try self . fileSystem. chmod ( . userWritable, path: checkoutPath , options: [ . recursive, . onlyFiles] )
34033412 try workingCopy. fetch ( )
3404- try ? self . fileSystem. chmod ( . userUnWritable, path: path , options: [ . recursive, . onlyFiles] )
3413+ try ? self . fileSystem. chmod ( . userUnWritable, path: checkoutPath , options: [ . recursive, . onlyFiles] )
34053414
3406- return path
3415+ return checkoutPath
34073416 }
34083417 }
34093418
34103419 // If not, we need to get the repository from the checkouts.
3411- let repository = try package . makeRepositorySpecifier ( )
34123420 // FIXME: this should not block
34133421 let handle = try temp_await {
34143422 self . repositoryManager. lookup (
@@ -3423,24 +3431,24 @@ extension Workspace {
34233431 }
34243432
34253433 // Clone the repository into the checkouts.
3426- let path = self . location. repositoriesCheckoutsDirectory. appending ( component: repository. basename)
3434+ let checkoutPath = self . location. repositoriesCheckoutsDirectory. appending ( component: repository. basename)
34273435
34283436 // Remove any existing content at that path.
3429- try self . fileSystem. chmod ( . userWritable, path: path , options: [ . recursive, . onlyFiles] )
3430- try self . fileSystem. removeFileTree ( path )
3437+ try self . fileSystem. chmod ( . userWritable, path: checkoutPath , options: [ . recursive, . onlyFiles] )
3438+ try self . fileSystem. removeFileTree ( checkoutPath )
34313439
34323440 // Inform the delegate that we're about to start.
3433- self . delegate? . willCreateWorkingCopy ( package : package . identity, repository: handle. repository. location. description, at: path )
3441+ self . delegate? . willCreateWorkingCopy ( package : package . identity, repository: handle. repository. location. description, at: checkoutPath )
34343442 let start = DispatchTime . now ( )
34353443
34363444 // Create the working copy.
3437- _ = try handle. createWorkingCopy ( at: path , editable: false )
3438-
3445+ _ = try handle. createWorkingCopy ( at: checkoutPath , editable: false )
3446+
34393447 // Inform the delegate that we're done.
34403448 let duration = start. distance ( to: . now( ) )
3441- self . delegate? . didCreateWorkingCopy ( package : package . identity, repository: handle. repository. location. description, at: path , duration: duration)
3449+ self . delegate? . didCreateWorkingCopy ( package : package . identity, repository: handle. repository. location. description, at: checkoutPath , duration: duration)
34423450
3443- return path
3451+ return checkoutPath
34443452 }
34453453
34463454 /// Removes the clone and checkout of the provided specifier.
0 commit comments