@@ -94,7 +94,7 @@ public struct GitRepositoryProvider: RepositoryProvider, Cancellable {
94
94
95
95
@discardableResult
96
96
private func callGit(
97
- _ args: String ... ,
97
+ _ args: [ String ] ,
98
98
environment: EnvironmentVariables = Git . environment,
99
99
repository: RepositorySpecifier ,
100
100
failureMessage: String = " " ,
@@ -133,6 +133,46 @@ public struct GitRepositoryProvider: RepositoryProvider, Cancellable {
133
133
}
134
134
}
135
135
136
+ @discardableResult
137
+ private func callGit(
138
+ _ args: String ... ,
139
+ environment: EnvironmentVariables = Git . environment,
140
+ repository: RepositorySpecifier ,
141
+ failureMessage: String = " " ,
142
+ progress: FetchProgress . Handler ? = nil
143
+ ) throws -> String {
144
+ try callGit (
145
+ args. map { $0 } ,
146
+ enviornment: environment,
147
+ repository: repository,
148
+ failureMessage: failureMessage,
149
+ progress: progress
150
+ )
151
+ }
152
+
153
+ private func clone(
154
+ _ repository: RepositorySpecifier ,
155
+ _ origin: String ,
156
+ _ destination: String ,
157
+ _ options: [ String ] ,
158
+ progress: FetchProgress . Handler ? = nil
159
+ ) throws {
160
+ let invocation : [ String ] = [
161
+ " clone " ,
162
+ // Enable symbolic links for Windows support.
163
+ " -c " , " core.symlinks=true " ,
164
+ // Disable fsmonitor to avoid spawning a monitor process.
165
+ " -c " , " core.fsmonitor=false " ,
166
+ ] + options + [ origin, destination]
167
+
168
+ try self . callGit (
169
+ invocation,
170
+ repository: repository,
171
+ failureMessage: " Failed to clone repository \( repository. location) " ,
172
+ progress: progress
173
+ )
174
+ }
175
+
136
176
public func fetch(
137
177
repository: RepositorySpecifier ,
138
178
to path: Basics . AbsolutePath ,
@@ -147,20 +187,11 @@ public struct GitRepositoryProvider: RepositoryProvider, Cancellable {
147
187
throw InternalError ( " \( path) already exists " )
148
188
}
149
189
150
- // NOTE: Explicitly set `core.symlinks=true` on `git clone` to ensure that symbolic links are correctly resolved.
151
- // NOTE: Explicitly set `core.fsmonitor` on `git clone` to ensure that we do not spawn a monitor on the repository. This is
152
- // particularly important for Windows where the process can prevent future operations.
153
- try self . callGit (
154
- " clone " ,
155
- " -c " ,
156
- " core.symlinks=true " ,
157
- " -c " ,
158
- " core.fsmonitor=false " ,
159
- " --mirror " ,
190
+ try self . clone (
191
+ repository,
160
192
repository. location. gitURL,
161
193
path. pathString,
162
- repository: repository,
163
- failureMessage: " Failed to clone repository \( repository. location) " ,
194
+ [ " --mirror " ] ,
164
195
progress: progressHandler
165
196
)
166
197
}
@@ -209,18 +240,14 @@ public struct GitRepositoryProvider: RepositoryProvider, Cancellable {
209
240
// For editable clones, i.e. the user is expected to directly work on them, first we create
210
241
// a clone from our cache of repositories and then we replace the remote to the one originally
211
242
// present in the bare repository.
212
- //
213
- // NOTE: Explicitly set `core.symlinks=true` on `git clone` to ensure that symbolic links are correctly resolved.
214
- try self . callGit (
215
- " clone " ,
216
- " -c " ,
217
- " core.symlinks=true " ,
218
- " --no-checkout " ,
243
+
244
+ try self . clone (
245
+ repository,
219
246
sourcePath. pathString,
220
247
destinationPath. pathString,
221
- repository: repository,
222
- failureMessage: " Failed to clone repository \( repository. location) "
248
+ [ " --no-checkout " ]
223
249
)
250
+
224
251
// The default name of the remote.
225
252
let origin = " origin "
226
253
// In destination repo remove the remote which will be pointing to the source repo.
@@ -238,18 +265,12 @@ public struct GitRepositoryProvider: RepositoryProvider, Cancellable {
238
265
// re-resolve such that the objects in this repository changed, we would
239
266
// only ever expect to get back a revision that remains present in the
240
267
// object storage.
241
- //
242
- // NOTE: Explicitly set `core.symlinks=true` on `git clone` to ensure that symbolic links are correctly resolved.
243
- try self . callGit (
244
- " clone " ,
245
- " -c " ,
246
- " core.symlinks=true " ,
247
- " --shared " ,
248
- " --no-checkout " ,
268
+
269
+ try self . clone (
270
+ repository,
249
271
sourcePath. pathString,
250
272
destinationPath. pathString,
251
- repository: repository,
252
- failureMessage: " Failed to clone repository \( repository. location) "
273
+ [ " --shared " , " --no-checkout " ]
253
274
)
254
275
}
255
276
return try self . openWorkingCopy ( at: destinationPath)
0 commit comments