Skip to content

Commit de9f512

Browse files
committed
Wrap all the various way of doing checkouts in GTCheckoutOptions
Fixes #457
1 parent 30219e2 commit de9f512

File tree

9 files changed

+199
-96
lines changed

9 files changed

+199
-96
lines changed

ObjectiveGit/GTCheckoutOptions.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//
2+
// GTCheckoutOptions.h
3+
// ObjectiveGitFramework
4+
//
5+
// Created by Etienne on 10/04/2015.
6+
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
#import "GTRepository.h"
11+
12+
/// Checkout strategies used by the various -checkout... methods
13+
/// See git_checkout_strategy_t
14+
typedef NS_OPTIONS(NSInteger, GTCheckoutStrategyType) {
15+
GTCheckoutStrategyNone = GIT_CHECKOUT_NONE,
16+
GTCheckoutStrategySafe = GIT_CHECKOUT_SAFE,
17+
GTCheckoutStrategyForce = GIT_CHECKOUT_FORCE,
18+
GTCheckoutStrategyAllowConflicts = GIT_CHECKOUT_ALLOW_CONFLICTS,
19+
GTCheckoutStrategyRemoveUntracked = GIT_CHECKOUT_REMOVE_UNTRACKED,
20+
GTCheckoutStrategyRemoveIgnored = GIT_CHECKOUT_REMOVE_IGNORED,
21+
GTCheckoutStrategyUpdateOnly = GIT_CHECKOUT_UPDATE_ONLY,
22+
GTCheckoutStrategyDontUpdateIndex = GIT_CHECKOUT_DONT_UPDATE_INDEX,
23+
GTCheckoutStrategyNoRefresh = GIT_CHECKOUT_NO_REFRESH,
24+
GTCheckoutStrategyDisablePathspecMatch = GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH,
25+
GTCheckoutStrategySkipLockedDirectories = GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES,
26+
};
27+
28+
/// Checkout notification flags used by the various -checkout... methods
29+
/// See git_checkout_notify_t
30+
typedef NS_OPTIONS(NSInteger, GTCheckoutNotifyFlags) {
31+
GTCheckoutNotifyNone = GIT_CHECKOUT_NOTIFY_NONE,
32+
GTCheckoutNotifyConflict = GIT_CHECKOUT_NOTIFY_CONFLICT,
33+
GTCheckoutNotifyDirty = GIT_CHECKOUT_NOTIFY_DIRTY,
34+
GTCheckoutNotifyUpdated = GIT_CHECKOUT_NOTIFY_UPDATED,
35+
GTCheckoutNotifyUntracked = GIT_CHECKOUT_NOTIFY_UNTRACKED,
36+
GTCheckoutNotifyIgnored = GIT_CHECKOUT_NOTIFY_IGNORED,
37+
38+
GTCheckoutNotifyAll = GIT_CHECKOUT_NOTIFY_ALL,
39+
};
40+
41+
@interface GTCheckoutOptions : NSObject
42+
+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags progressBlock:(void (^)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps))progressBlock notifyBlock:(int (^)(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir))notifyBlock;
43+
44+
+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy progressBlock:(void (^)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps))progressBlock;
45+
46+
+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy;
47+
48+
- (git_checkout_options *)git_checkoutOptions NS_RETURNS_INNER_POINTER;
49+
50+
@property (assign) GTCheckoutStrategyType strategy;
51+
@property (copy) void (^progressBlock)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps);
52+
53+
@property (assign) GTCheckoutNotifyFlags notifyFlags;
54+
@property (copy) int (^notifyBlock)(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir);
55+
@end

ObjectiveGit/GTCheckoutOptions.m

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//
2+
// GTCheckoutOptions.m
3+
// ObjectiveGitFramework
4+
//
5+
// Created by Etienne on 10/04/2015.
6+
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
7+
//
8+
9+
#import "GTCheckoutOptions.h"
10+
#import "GTDiffFile.h"
11+
#import "NSError+Git.h"
12+
#import "git2.h"
13+
14+
// The type of block passed to -checkout:strategy:progressBlock:notifyBlock:notifyFlags:error: for progress reporting
15+
typedef void (^GTCheckoutProgressBlock)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps);
16+
17+
// The type of block passed to -checkout:strategy:progressBlock:notifyBlock:notifyFlags:error: for notification reporting
18+
typedef int (^GTCheckoutNotifyBlock)(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir);
19+
20+
21+
@interface GTCheckoutOptions () {
22+
git_checkout_options _git_checkoutOptions;
23+
}
24+
@end
25+
26+
@implementation GTCheckoutOptions
27+
28+
+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags progressBlock:(GTCheckoutProgressBlock)progressBlock notifyBlock:(GTCheckoutNotifyBlock)notifyBlock {
29+
GTCheckoutOptions *options = [self checkoutOptionsWithStrategy:strategy progressBlock:progressBlock];
30+
options.notifyFlags = notifyFlags;
31+
options.notifyBlock = notifyBlock;
32+
return options;
33+
}
34+
35+
+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy progressBlock:(GTCheckoutProgressBlock)progressBlock {
36+
GTCheckoutOptions *options = [self checkoutOptionsWithStrategy:strategy];
37+
options.progressBlock = progressBlock;
38+
return options;
39+
}
40+
41+
+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy {
42+
GTCheckoutOptions *options = [[self alloc] init];
43+
options.strategy = strategy;
44+
return options;
45+
}
46+
47+
- (instancetype)init {
48+
self = [super init];
49+
if (self == nil) return nil;
50+
51+
_git_checkoutOptions.version = GIT_CHECKOUT_OPTIONS_VERSION;
52+
53+
return self;
54+
}
55+
56+
static void GTCheckoutProgressCallback(const char *path, size_t completedSteps, size_t totalSteps, void *payload) {
57+
if (payload == NULL) return;
58+
void (^block)(NSString *, NSUInteger, NSUInteger) = (__bridge id)payload;
59+
NSString *nsPath = (path != NULL ? [NSString stringWithUTF8String:path] : nil);
60+
block(nsPath, completedSteps, totalSteps);
61+
}
62+
63+
static int GTCheckoutNotifyCallback(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) {
64+
if (payload == NULL) return 0;
65+
GTCheckoutNotifyBlock block = (__bridge id)payload;
66+
NSString *nsPath = (path != NULL ? @(path) : nil);
67+
GTDiffFile *gtBaseline = (baseline != NULL ? [[GTDiffFile alloc] initWithGitDiffFile:*baseline] : nil);
68+
GTDiffFile *gtTarget = (target != NULL ? [[GTDiffFile alloc] initWithGitDiffFile:*target] : nil);
69+
GTDiffFile *gtWorkdir = (workdir != NULL ? [[GTDiffFile alloc] initWithGitDiffFile:*workdir] : nil);
70+
return block((GTCheckoutNotifyFlags)why, nsPath, gtBaseline, gtTarget, gtWorkdir);
71+
}
72+
73+
- (git_checkout_options *)git_checkoutOptions {
74+
_git_checkoutOptions.checkout_strategy = self.strategy;
75+
76+
if (self.progressBlock) {
77+
_git_checkoutOptions.progress_cb = GTCheckoutProgressCallback;
78+
_git_checkoutOptions.progress_payload = (__bridge void *)self.progressBlock;
79+
}
80+
81+
if (self.notifyBlock) {
82+
_git_checkoutOptions.notify_cb = GTCheckoutNotifyCallback;
83+
_git_checkoutOptions.notify_flags = self.notifyFlags;
84+
_git_checkoutOptions.notify_payload = (__bridge void *)self.notifyBlock;
85+
}
86+
87+
return &_git_checkoutOptions;
88+
}
89+
90+
@end

ObjectiveGit/GTRepository.h

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,35 +51,7 @@
5151
@class GTTag;
5252
@class GTTree;
5353
@class GTRemote;
54-
55-
/// Checkout strategies used by the various -checkout... methods
56-
/// See git_checkout_strategy_t
57-
typedef NS_OPTIONS(NSInteger, GTCheckoutStrategyType) {
58-
GTCheckoutStrategyNone = GIT_CHECKOUT_NONE,
59-
GTCheckoutStrategySafe = GIT_CHECKOUT_SAFE,
60-
GTCheckoutStrategyForce = GIT_CHECKOUT_FORCE,
61-
GTCheckoutStrategyAllowConflicts = GIT_CHECKOUT_ALLOW_CONFLICTS,
62-
GTCheckoutStrategyRemoveUntracked = GIT_CHECKOUT_REMOVE_UNTRACKED,
63-
GTCheckoutStrategyRemoveIgnored = GIT_CHECKOUT_REMOVE_IGNORED,
64-
GTCheckoutStrategyUpdateOnly = GIT_CHECKOUT_UPDATE_ONLY,
65-
GTCheckoutStrategyDontUpdateIndex = GIT_CHECKOUT_DONT_UPDATE_INDEX,
66-
GTCheckoutStrategyNoRefresh = GIT_CHECKOUT_NO_REFRESH,
67-
GTCheckoutStrategyDisablePathspecMatch = GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH,
68-
GTCheckoutStrategySkipLockedDirectories = GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES,
69-
};
70-
71-
/// Checkout notification flags used by the various -checkout... methods
72-
/// See git_checkout_notify_t
73-
typedef NS_OPTIONS(NSInteger, GTCheckoutNotifyFlags) {
74-
GTCheckoutNotifyNone = GIT_CHECKOUT_NOTIFY_NONE,
75-
GTCheckoutNotifyConflict = GIT_CHECKOUT_NOTIFY_CONFLICT,
76-
GTCheckoutNotifyDirty = GIT_CHECKOUT_NOTIFY_DIRTY,
77-
GTCheckoutNotifyUpdated = GIT_CHECKOUT_NOTIFY_UPDATED,
78-
GTCheckoutNotifyUntracked = GIT_CHECKOUT_NOTIFY_UNTRACKED,
79-
GTCheckoutNotifyIgnored = GIT_CHECKOUT_NOTIFY_IGNORED,
80-
81-
GTCheckoutNotifyAll = GIT_CHECKOUT_NOTIFY_ALL,
82-
};
54+
@class GTCheckoutOptions;
8355

8456
/// Transport flags sent as options to +cloneFromURL... method
8557
typedef NS_OPTIONS(NSInteger, GTTransportFlags) {
@@ -98,6 +70,9 @@ extern NSString * const GTRepositoryCloneOptionsBare;
9870
/// Default value is `YES`.
9971
extern NSString * const GTRepositoryCloneOptionsCheckout;
10072

73+
/// A `GTCheckoutOptions` object describing how to perform the checkout.
74+
extern NSString * const GTRepositoryCloneCheckoutOptions;
75+
10176
/// A `GTCredentialProvider`, that will be used to authenticate against the
10277
/// remote.
10378
extern NSString * const GTRepositoryCloneOptionsCredentialProvider;
@@ -199,7 +174,7 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
199174
/// options - A dictionary consisting of the options:
200175
/// `GTRepositoryCloneOptionsTransportFlags`,
201176
/// `GTRepositoryCloneOptionsBare`,
202-
/// `GTRepositoryCloneOptionsCheckout`,
177+
/// `GTRepositoryCloneCheckoutOptions`,
203178
/// `GTRepositoryCloneOptionsCredentialProvider`,
204179
/// `GTRepositoryCloneOptionsCloneLocal`,
205180
/// `GTRepositoryCloneOptionsServerCertificateURL`
@@ -209,6 +184,9 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
209184
/// (if `GTRepositoryCloneOptionsCheckout` is YES).
210185
///
211186
/// returns nil (and fills the error parameter) if an error occurred, or a GTRepository object if successful.
187+
+ (id)cloneFromURL:(NSURL *)originURL toWorkingDirectory:(NSURL *)workdirURL options:(NSDictionary *)options error:(NSError **)error transferProgressBlock:(void (^)(const git_transfer_progress *, BOOL *stop))transferProgressBlock;
188+
189+
/// Backward-compatible method that uses `GTRepositoryCloneOptionsCheckout`
212190
+ (id)cloneFromURL:(NSURL *)originURL toWorkingDirectory:(NSURL *)workdirURL options:(NSDictionary *)options error:(NSError **)error transferProgressBlock:(void (^)(const git_transfer_progress *, BOOL *stop))transferProgressBlock checkoutProgressBlock:(void (^)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps))checkoutProgressBlock;
213191

214192
/// Lookup objects in the repo by oid or sha1
@@ -454,7 +432,7 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
454432
/// progressBlock - The block to call back for progress updates. Can be nil.
455433
///
456434
/// Returns YES if operation was successful, NO otherwise
457-
- (BOOL)checkoutCommit:(GTCommit *)targetCommit strategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags error:(NSError **)error progressBlock:(void (^)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps))progressBlock notifyBlock:(int (^)(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir))notifyBlock;
435+
- (BOOL)checkoutCommit:(GTCommit *)targetCommit options:(GTCheckoutOptions *)options error:(NSError **)error;
458436

459437
/// Checkout a reference
460438
///
@@ -467,13 +445,13 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
467445
/// progressBlock - The block to call back for progress updates. Can be nil.
468446
///
469447
/// Returns YES if operation was successful, NO otherwise
470-
- (BOOL)checkoutReference:(GTReference *)targetReference strategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags error:(NSError **)error progressBlock:(void (^)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps))progressBlock notifyBlock:(int (^)(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir))notifyBlock;
448+
- (BOOL)checkoutReference:(GTReference *)targetReference options:(GTCheckoutOptions *)options error:(NSError **)error;
471449

472450
/// Convenience wrapper for checkoutCommit:strategy:notifyFlags:error:notifyBlock:progressBlock without notifications
473-
- (BOOL)checkoutCommit:(GTCommit *)target strategy:(GTCheckoutStrategyType)strategy error:(NSError **)error progressBlock:(void (^)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps))progressBlock;
451+
//- (BOOL)checkoutCommit:(GTCommit *)target options:(GTCheckoutOptions *)options error:(NSError **)error;
474452

475453
/// Convenience wrapper for checkoutReference:strategy:notifyFlags:error:notifyBlock:progressBlock without notifications
476-
- (BOOL)checkoutReference:(GTReference *)target strategy:(GTCheckoutStrategyType)strategy error:(NSError **)error progressBlock:(void (^)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps))progressBlock;
454+
//- (BOOL)checkoutReference:(GTReference *)target options:(GTCheckoutOptions *)options error:(NSError **)error;
477455

478456
/// Flush the gitattributes cache.
479457
- (void)flushAttributesCache;

0 commit comments

Comments
 (0)