31
31
32
32
#import " GTBlob.h"
33
33
#import " GTBranch.h"
34
+ #import " GTCheckoutOptions.h"
34
35
#import " GTCommit.h"
35
36
#import " GTConfiguration+Private.h"
36
37
#import " GTConfiguration.h"
59
60
#import " git2.h"
60
61
61
62
NSString * const GTRepositoryCloneOptionsBare = @" GTRepositoryCloneOptionsBare" ;
62
- NSString * const GTRepositoryCloneOptionsCheckout = @" GTRepositoryCloneOptionsCheckout " ;
63
+ NSString * const GTRepositoryCloneCheckoutOptions = @" GTRepositoryCloneCheckoutOptions " ;
63
64
NSString * const GTRepositoryCloneOptionsTransportFlags = @" GTRepositoryCloneOptionsTransportFlags" ;
64
65
NSString * const GTRepositoryCloneOptionsCredentialProvider = @" GTRepositoryCloneOptionsCredentialProvider" ;
65
66
NSString * const GTRepositoryCloneOptionsCloneLocal = @" GTRepositoryCloneOptionsCloneLocal" ;
@@ -212,18 +213,11 @@ - (instancetype)initWithURL:(NSURL *)localFileURL flags:(NSInteger)flags ceiling
212
213
213
214
typedef void (^GTTransferProgressBlock)(const git_transfer_progress *progress, BOOL *stop);
214
215
215
- static void checkoutProgressCallback (const char *path, size_t completedSteps, size_t totalSteps, void *payload) {
216
- if (payload == NULL ) return ;
217
- void (^block)(NSString *, NSUInteger , NSUInteger ) = (__bridge id )payload;
218
- NSString *nsPath = (path != NULL ? [NSString stringWithUTF8String: path] : nil );
219
- block (nsPath, completedSteps, totalSteps);
220
- }
221
-
222
216
static int transferProgressCallback (const git_transfer_progress *progress, void *payload) {
223
217
if (payload == NULL ) return 0 ;
224
218
struct GTClonePayload *pld = payload;
225
219
if (pld->transferProgressBlock == NULL ) return 0 ;
226
-
220
+
227
221
BOOL stop = NO ;
228
222
pld->transferProgressBlock (progress, &stop);
229
223
return (stop ? GIT_EUSER : 0 );
@@ -243,22 +237,20 @@ static int remoteCreate(git_remote **remote, git_repository *repo, const char *n
243
237
return GIT_OK;
244
238
}
245
239
246
- + (instancetype )cloneFromURL : (NSURL *)originURL toWorkingDirectory : (NSURL *)workdirURL options : (NSDictionary *)options error : (NSError **)error transferProgressBlock : (void (^)(const git_transfer_progress *, BOOL *stop))transferProgressBlock checkoutProgressBlock : (void (^)(NSString *__nullable path, NSUInteger completedSteps, NSUInteger totalSteps))checkoutProgressBlock {
240
+ struct GTRemoteCreatePayload {
241
+ git_remote_callbacks remoteCallbacks;
242
+ };
243
+
244
+ + (nullable instancetype )cloneFromURL : (NSURL *)originURL toWorkingDirectory : (NSURL *)workdirURL options : (nullable NSDictionary *)options error : (NSError **)error transferProgressBlock : (nullable void (^)(const git_transfer_progress *, BOOL *stop))transferProgressBlock {
247
245
248
246
git_clone_options cloneOptions = GIT_CLONE_OPTIONS_INIT;
249
247
250
248
NSNumber *bare = options[GTRepositoryCloneOptionsBare];
251
249
cloneOptions.bare = (bare == nil ? 0 : bare.boolValue );
252
250
253
- NSNumber *checkout = options[GTRepositoryCloneOptionsCheckout];
254
- BOOL withCheckout = (checkout == nil ? YES : checkout.boolValue );
255
-
256
- if (withCheckout) {
257
- git_checkout_options checkoutOptions = GIT_CHECKOUT_OPTIONS_INIT;
258
- checkoutOptions.checkout_strategy = GIT_CHECKOUT_SAFE;
259
- checkoutOptions.progress_cb = checkoutProgressCallback;
260
- checkoutOptions.progress_payload = (__bridge void *)checkoutProgressBlock;
261
- cloneOptions.checkout_opts = checkoutOptions;
251
+ GTCheckoutOptions *checkoutOptions = options[GTRepositoryCloneCheckoutOptions];
252
+ if (checkoutOptions != nil ) {
253
+ cloneOptions.checkout_opts = *(checkoutOptions.git_checkoutOptions );
262
254
}
263
255
264
256
GTCredentialProvider *provider = options[GTRepositoryCloneOptionsCredentialProvider];
@@ -284,7 +276,7 @@ + (instancetype)cloneFromURL:(NSURL *)originURL toWorkingDirectory:(NSURL *)work
284
276
if (localClone) {
285
277
cloneOptions.local = GIT_CLONE_NO_LOCAL;
286
278
}
287
-
279
+
288
280
NSURL *serverCertificateURL = options[GTRepositoryCloneOptionsServerCertificateURL];
289
281
if (serverCertificateURL) {
290
282
int gitError = git_libgit2_opts (GIT_OPT_SET_SSL_CERT_LOCATIONS, serverCertificateURL.fileSystemRepresentation , NULL );
@@ -310,8 +302,6 @@ + (instancetype)cloneFromURL:(NSURL *)originURL toWorkingDirectory:(NSURL *)work
310
302
}
311
303
312
304
return [[self alloc ] initWithGitRepository: repository];
313
-
314
- return nil ;
315
305
}
316
306
317
307
- (id )lookUpObjectByGitOid : (const git_oid *)oid objectType : (GTObjectType)type error : (NSError **)error {
@@ -795,22 +785,6 @@ - (GTTag *)createTagNamed:(NSString *)tagName target:(GTObject *)theTarget tagge
795
785
796
786
#pragma mark Checkout
797
787
798
- // The type of block passed to -checkout:strategy:progressBlock:notifyBlock:notifyFlags:error: for progress reporting
799
- typedef void (^GTCheckoutProgressBlock)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps);
800
-
801
- // The type of block passed to -checkout:strategy:progressBlock:notifyBlock:notifyFlags:error: for notification reporting
802
- typedef int (^GTCheckoutNotifyBlock)(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir);
803
-
804
- static int checkoutNotifyCallback (git_checkout_notify_t why, const char *path, const git_diff_file *baseline, const git_diff_file *target, const git_diff_file *workdir, void *payload) {
805
- if (payload == NULL ) return 0 ;
806
- GTCheckoutNotifyBlock block = (__bridge id )payload;
807
- NSString *nsPath = (path != NULL ? @(path) : nil );
808
- GTDiffFile *gtBaseline = (baseline != NULL ? [[GTDiffFile alloc ] initWithGitDiffFile: *baseline] : nil );
809
- GTDiffFile *gtTarget = (target != NULL ? [[GTDiffFile alloc ] initWithGitDiffFile: *target] : nil );
810
- GTDiffFile *gtWorkdir = (workdir != NULL ? [[GTDiffFile alloc ] initWithGitDiffFile: *workdir] : nil );
811
- return block ((GTCheckoutNotifyFlags)why, nsPath, gtBaseline, gtTarget, gtWorkdir);
812
- }
813
-
814
788
- (BOOL )moveHEADToReference : (GTReference *)reference error : (NSError **)error {
815
789
NSParameterAssert (reference != nil );
816
790
@@ -833,51 +807,40 @@ - (BOOL)moveHEADToCommit:(GTCommit *)commit error:(NSError **)error {
833
807
return gitError == GIT_OK;
834
808
}
835
809
836
- - (BOOL )performCheckout : (GTObject *)target withStrategy : (GTCheckoutStrategyType)strategy notifyFlags : (GTCheckoutNotifyFlags)notifyFlags error : (NSError **)error progressBlock : (GTCheckoutProgressBlock)progressBlock notifyBlock : (GTCheckoutNotifyBlock)notifyBlock {
837
-
838
- git_checkout_options checkoutOptions = GIT_CHECKOUT_OPTIONS_INIT;
839
-
840
- checkoutOptions.checkout_strategy = strategy;
841
- checkoutOptions.progress_cb = checkoutProgressCallback;
842
- checkoutOptions.progress_payload = (__bridge void *)progressBlock;
843
-
844
- checkoutOptions.notify_cb = checkoutNotifyCallback;
845
- checkoutOptions.notify_flags = notifyFlags;
846
- checkoutOptions.notify_payload = (__bridge void *)notifyBlock;
847
-
848
- int gitError = git_checkout_tree (self.git_repository , target.git_object , &checkoutOptions);
810
+ - (BOOL )performCheckout : (GTObject *)target options : (nullable GTCheckoutOptions *)options error : (NSError **)error {
811
+ int gitError = git_checkout_tree (self.git_repository , target.git_object , options.git_checkoutOptions );
849
812
if (gitError < GIT_OK) {
850
813
if (error != NULL ) *error = [NSError git_errorFor: gitError description: @" Failed to checkout tree." ];
851
814
}
852
-
853
815
return gitError == GIT_OK;
854
816
}
855
817
856
- - (BOOL )checkoutCommit : (GTCommit *)targetCommit strategy : (GTCheckoutStrategyType) strategy notifyFlags : (GTCheckoutNotifyFlags) notifyFlags error : (NSError **)error progressBlock : (GTCheckoutProgressBlock) progressBlock notifyBlock : (GTCheckoutNotifyBlock) notifyBlock {
857
- BOOL success = [self performCheckout: targetCommit withStrategy: strategy notifyFlags: notifyFlags error: error progressBlock: progressBlock notifyBlock: notifyBlock ];
818
+ - (BOOL )checkoutCommit : (GTCommit *)targetCommit options : (GTCheckoutOptions *) options error : (NSError **)error {
819
+ BOOL success = [self performCheckout: targetCommit options: options error: error];
858
820
if (success == NO ) return NO ;
859
821
return [self moveHEADToCommit: targetCommit error: error];
860
822
}
861
823
862
- - (BOOL )checkoutReference : (GTReference *)targetReference strategy : (GTCheckoutStrategyType) strategy notifyFlags : (GTCheckoutNotifyFlags) notifyFlags error : (NSError **)error progressBlock : (GTCheckoutProgressBlock) progressBlock notifyBlock : (GTCheckoutNotifyBlock) notifyBlock {
824
+ - (BOOL )checkoutReference : (GTReference *)targetReference options : (GTCheckoutOptions *) options error : (NSError **)error {
863
825
GTOID *targetOID = [targetReference targetOID ];
864
826
GTObject *target = [self lookUpObjectByOID: targetOID error: error];
865
827
if (target == nil ) return NO ;
866
- BOOL success = [self performCheckout: target withStrategy: strategy notifyFlags: notifyFlags error: error progressBlock: progressBlock notifyBlock: notifyBlock ];
828
+ BOOL success = [self performCheckout: target options: options error: error];
867
829
if (success == NO ) return NO ;
868
830
return [self moveHEADToReference: targetReference error: error];
869
831
}
870
832
871
- - (BOOL )checkoutTree : (GTTree *)targetTree strategy : (GTCheckoutStrategyType) strategy notifyFlags : (GTCheckoutNotifyFlags) notifyFlags error : (NSError **)error progressBlock : (GTCheckoutProgressBlock) progressBlock notifyBlock : (GTCheckoutNotifyBlock) notifyBlock {
872
- return [self performCheckout: targetTree withStrategy: strategy notifyFlags: notifyFlags error: error progressBlock: progressBlock notifyBlock: notifyBlock ];
833
+ - (BOOL )checkoutTree : (GTTree *)targetTree options : (nullable GTCheckoutOptions *) options error : (NSError **)error {
834
+ return [self performCheckout: targetTree options: options error: error];
873
835
}
874
836
875
- - (BOOL )checkoutCommit : (GTCommit *)target strategy : (GTCheckoutStrategyType)strategy error : (NSError **)error progressBlock : (GTCheckoutProgressBlock)progressBlock {
876
- return [self checkoutCommit: target strategy: strategy notifyFlags: GTCheckoutNotifyNone error: error progressBlock: progressBlock notifyBlock: nil ];
877
- }
878
-
879
- - (BOOL )checkoutReference : (GTReference *)target strategy : (GTCheckoutStrategyType)strategy error : (NSError **)error progressBlock : (GTCheckoutProgressBlock)progressBlock {
880
- return [self checkoutReference: target strategy: strategy notifyFlags: GTCheckoutNotifyNone error: error progressBlock: progressBlock notifyBlock: nil ];
837
+ - (BOOL )checkoutIndex : (GTIndex *)index options : (GTCheckoutOptions *)options error : (NSError **)error {
838
+ int gitError = git_checkout_index (self.git_repository , index .git_index , options.git_checkoutOptions );
839
+ if (gitError < GIT_OK) {
840
+ if (error != NULL ) *error = [NSError git_errorFor: gitError description: @" Failed to checkout index." ];
841
+ return NO ;
842
+ }
843
+ return YES ;
881
844
}
882
845
883
846
- (void )flushAttributesCache {
0 commit comments