@@ -3652,8 +3652,13 @@ extension Workspace {
3652
3652
observabilityScope: ObservabilityScope
3653
3653
) throws -> AbsolutePath {
3654
3654
let repository = try package . makeRepositorySpecifier ( )
3655
- // first fetch the repository.
3656
- let checkoutPath = try self . fetchRepository ( package : package , observabilityScope: observabilityScope)
3655
+
3656
+ // first fetch the repository
3657
+ let checkoutPath = try self . fetchRepository (
3658
+ package : package ,
3659
+ at: checkoutState. revision,
3660
+ observabilityScope: observabilityScope
3661
+ )
3657
3662
3658
3663
// Check out the given revision.
3659
3664
let workingCopy = try self . repositoryManager. openWorkingCopy ( at: checkoutPath)
@@ -3722,37 +3727,40 @@ extension Workspace {
3722
3727
///
3723
3728
/// - Returns: The path of the local repository.
3724
3729
/// - Throws: If the operation could not be satisfied.
3725
- private func fetchRepository( package : PackageReference , observabilityScope: ObservabilityScope ) throws -> AbsolutePath {
3730
+ private func fetchRepository(
3731
+ package : PackageReference ,
3732
+ at revision: Revision ,
3733
+ observabilityScope: ObservabilityScope
3734
+ ) throws -> AbsolutePath {
3735
+ let repository = try package . makeRepositorySpecifier ( )
3736
+
3726
3737
// If we already have it, fetch to update the repo from its remote.
3727
3738
// also compare the location as it may have changed
3728
3739
if let dependency = self . state. dependencies [ comparingLocation: package ] {
3729
- let path = self . location. repositoriesCheckoutSubdirectory ( for: dependency)
3740
+ let checkoutPath = self . location. repositoriesCheckoutSubdirectory ( for: dependency)
3730
3741
3731
- // Make sure the directory is not missing (we will have to clone again
3732
- // if not) .
3733
- fetch: if self . fileSystem. isDirectory ( path ) {
3742
+ // Make sure the directory is not missing (we will have to clone again if not).
3743
+ // This can become invalid if the build directory is moved .
3744
+ fetch: if self . fileSystem. isDirectory ( checkoutPath ) {
3734
3745
// Fetch the checkout in case there are updates available.
3735
- let workingCopy = try self . repositoryManager. openWorkingCopy ( at: path )
3746
+ let workingCopy = try self . repositoryManager. openWorkingCopy ( at: checkoutPath )
3736
3747
3737
3748
// Ensure that the alternative object store is still valid.
3738
- //
3739
- // This can become invalid if the build directory is moved.
3740
- guard workingCopy. isAlternateObjectStoreValid ( ) else {
3749
+ guard try self . repositoryManager. isValidWorkingCopy ( workingCopy, for: repository) else {
3750
+ observabilityScope. emit ( debug: " working copy at ' \( checkoutPath) ' does not align with expected local path of ' \( repository) ' " )
3741
3751
break fetch
3742
3752
}
3743
3753
3744
- // The fetch operation may update contents of the checkout, so
3745
3754
// we need do mutable-immutable dance.
3746
- try self . fileSystem. chmod ( . userWritable, path: path , options: [ . recursive, . onlyFiles] )
3755
+ try self . fileSystem. chmod ( . userWritable, path: checkoutPath , options: [ . recursive, . onlyFiles] )
3747
3756
try workingCopy. fetch ( )
3748
- try ? self . fileSystem. chmod ( . userUnWritable, path: path , options: [ . recursive, . onlyFiles] )
3757
+ try ? self . fileSystem. chmod ( . userUnWritable, path: checkoutPath , options: [ . recursive, . onlyFiles] )
3749
3758
3750
- return path
3759
+ return checkoutPath
3751
3760
}
3752
3761
}
3753
3762
3754
3763
// If not, we need to get the repository from the checkouts.
3755
- let repository = try package . makeRepositorySpecifier ( )
3756
3764
// FIXME: this should not block
3757
3765
let handle = try temp_await {
3758
3766
self . repositoryManager. lookup (
@@ -3767,24 +3775,24 @@ extension Workspace {
3767
3775
}
3768
3776
3769
3777
// Clone the repository into the checkouts.
3770
- let path = self . location. repositoriesCheckoutsDirectory. appending ( component: repository. basename)
3778
+ let checkoutPath = self . location. repositoriesCheckoutsDirectory. appending ( component: repository. basename)
3771
3779
3772
3780
// Remove any existing content at that path.
3773
- try self . fileSystem. chmod ( . userWritable, path: path , options: [ . recursive, . onlyFiles] )
3774
- try self . fileSystem. removeFileTree ( path )
3781
+ try self . fileSystem. chmod ( . userWritable, path: checkoutPath , options: [ . recursive, . onlyFiles] )
3782
+ try self . fileSystem. removeFileTree ( checkoutPath )
3775
3783
3776
3784
// Inform the delegate that we're about to start.
3777
- self . delegate? . willCreateWorkingCopy ( package : package . identity, repository: handle. repository. location. description, at: path )
3785
+ self . delegate? . willCreateWorkingCopy ( package : package . identity, repository: handle. repository. location. description, at: checkoutPath )
3778
3786
let start = DispatchTime . now ( )
3779
3787
3780
3788
// Create the working copy.
3781
- _ = try handle. createWorkingCopy ( at: path , editable: false )
3782
-
3789
+ _ = try handle. createWorkingCopy ( at: checkoutPath , editable: false )
3790
+
3783
3791
// Inform the delegate that we're done.
3784
3792
let duration = start. distance ( to: . now( ) )
3785
- self . delegate? . didCreateWorkingCopy ( package : package . identity, repository: handle. repository. location. description, at: path , duration: duration)
3793
+ self . delegate? . didCreateWorkingCopy ( package : package . identity, repository: handle. repository. location. description, at: checkoutPath , duration: duration)
3786
3794
3787
- return path
3795
+ return checkoutPath
3788
3796
}
3789
3797
3790
3798
/// Removes the clone and checkout of the provided specifier.
0 commit comments