Skip to content

Commit

Permalink
Wrap all the various way of doing checkouts in GTCheckoutOptions
Browse files Browse the repository at this point in the history
Fixes #457
  • Loading branch information
tiennou committed Apr 10, 2015
1 parent 30219e2 commit de9f512
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 96 deletions.
55 changes: 55 additions & 0 deletions ObjectiveGit/GTCheckoutOptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// GTCheckoutOptions.h
// ObjectiveGitFramework
//
// Created by Etienne on 10/04/2015.
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "GTRepository.h"

/// Checkout strategies used by the various -checkout... methods
/// See git_checkout_strategy_t
typedef NS_OPTIONS(NSInteger, GTCheckoutStrategyType) {
GTCheckoutStrategyNone = GIT_CHECKOUT_NONE,
GTCheckoutStrategySafe = GIT_CHECKOUT_SAFE,
GTCheckoutStrategyForce = GIT_CHECKOUT_FORCE,
GTCheckoutStrategyAllowConflicts = GIT_CHECKOUT_ALLOW_CONFLICTS,
GTCheckoutStrategyRemoveUntracked = GIT_CHECKOUT_REMOVE_UNTRACKED,
GTCheckoutStrategyRemoveIgnored = GIT_CHECKOUT_REMOVE_IGNORED,
GTCheckoutStrategyUpdateOnly = GIT_CHECKOUT_UPDATE_ONLY,
GTCheckoutStrategyDontUpdateIndex = GIT_CHECKOUT_DONT_UPDATE_INDEX,
GTCheckoutStrategyNoRefresh = GIT_CHECKOUT_NO_REFRESH,
GTCheckoutStrategyDisablePathspecMatch = GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH,
GTCheckoutStrategySkipLockedDirectories = GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES,
};

/// Checkout notification flags used by the various -checkout... methods
/// See git_checkout_notify_t
typedef NS_OPTIONS(NSInteger, GTCheckoutNotifyFlags) {
GTCheckoutNotifyNone = GIT_CHECKOUT_NOTIFY_NONE,
GTCheckoutNotifyConflict = GIT_CHECKOUT_NOTIFY_CONFLICT,
GTCheckoutNotifyDirty = GIT_CHECKOUT_NOTIFY_DIRTY,
GTCheckoutNotifyUpdated = GIT_CHECKOUT_NOTIFY_UPDATED,
GTCheckoutNotifyUntracked = GIT_CHECKOUT_NOTIFY_UNTRACKED,
GTCheckoutNotifyIgnored = GIT_CHECKOUT_NOTIFY_IGNORED,

GTCheckoutNotifyAll = GIT_CHECKOUT_NOTIFY_ALL,
};

@interface GTCheckoutOptions : NSObject
+ (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;

+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy progressBlock:(void (^)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps))progressBlock;

+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy;

- (git_checkout_options *)git_checkoutOptions NS_RETURNS_INNER_POINTER;

@property (assign) GTCheckoutStrategyType strategy;
@property (copy) void (^progressBlock)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps);

@property (assign) GTCheckoutNotifyFlags notifyFlags;
@property (copy) int (^notifyBlock)(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir);
@end
90 changes: 90 additions & 0 deletions ObjectiveGit/GTCheckoutOptions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// GTCheckoutOptions.m
// ObjectiveGitFramework
//
// Created by Etienne on 10/04/2015.
// Copyright (c) 2015 GitHub, Inc. All rights reserved.
//

#import "GTCheckoutOptions.h"
#import "GTDiffFile.h"
#import "NSError+Git.h"
#import "git2.h"

// The type of block passed to -checkout:strategy:progressBlock:notifyBlock:notifyFlags:error: for progress reporting
typedef void (^GTCheckoutProgressBlock)(NSString *path, NSUInteger completedSteps, NSUInteger totalSteps);

// The type of block passed to -checkout:strategy:progressBlock:notifyBlock:notifyFlags:error: for notification reporting
typedef int (^GTCheckoutNotifyBlock)(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir);


@interface GTCheckoutOptions () {
git_checkout_options _git_checkoutOptions;
}
@end

@implementation GTCheckoutOptions

+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags progressBlock:(GTCheckoutProgressBlock)progressBlock notifyBlock:(GTCheckoutNotifyBlock)notifyBlock {
GTCheckoutOptions *options = [self checkoutOptionsWithStrategy:strategy progressBlock:progressBlock];
options.notifyFlags = notifyFlags;
options.notifyBlock = notifyBlock;
return options;
}

+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy progressBlock:(GTCheckoutProgressBlock)progressBlock {
GTCheckoutOptions *options = [self checkoutOptionsWithStrategy:strategy];
options.progressBlock = progressBlock;
return options;
}

+ (instancetype)checkoutOptionsWithStrategy:(GTCheckoutStrategyType)strategy {
GTCheckoutOptions *options = [[self alloc] init];
options.strategy = strategy;
return options;
}

- (instancetype)init {
self = [super init];
if (self == nil) return nil;

_git_checkoutOptions.version = GIT_CHECKOUT_OPTIONS_VERSION;

return self;
}

static void GTCheckoutProgressCallback(const char *path, size_t completedSteps, size_t totalSteps, void *payload) {
if (payload == NULL) return;
void (^block)(NSString *, NSUInteger, NSUInteger) = (__bridge id)payload;
NSString *nsPath = (path != NULL ? [NSString stringWithUTF8String:path] : nil);
block(nsPath, completedSteps, totalSteps);
}

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) {
if (payload == NULL) return 0;
GTCheckoutNotifyBlock block = (__bridge id)payload;
NSString *nsPath = (path != NULL ? @(path) : nil);
GTDiffFile *gtBaseline = (baseline != NULL ? [[GTDiffFile alloc] initWithGitDiffFile:*baseline] : nil);
GTDiffFile *gtTarget = (target != NULL ? [[GTDiffFile alloc] initWithGitDiffFile:*target] : nil);
GTDiffFile *gtWorkdir = (workdir != NULL ? [[GTDiffFile alloc] initWithGitDiffFile:*workdir] : nil);
return block((GTCheckoutNotifyFlags)why, nsPath, gtBaseline, gtTarget, gtWorkdir);
}

- (git_checkout_options *)git_checkoutOptions {
_git_checkoutOptions.checkout_strategy = self.strategy;

if (self.progressBlock) {
_git_checkoutOptions.progress_cb = GTCheckoutProgressCallback;
_git_checkoutOptions.progress_payload = (__bridge void *)self.progressBlock;
}

if (self.notifyBlock) {
_git_checkoutOptions.notify_cb = GTCheckoutNotifyCallback;
_git_checkoutOptions.notify_flags = self.notifyFlags;
_git_checkoutOptions.notify_payload = (__bridge void *)self.notifyBlock;
}

return &_git_checkoutOptions;
}

@end
46 changes: 12 additions & 34 deletions ObjectiveGit/GTRepository.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,35 +51,7 @@
@class GTTag;
@class GTTree;
@class GTRemote;

/// Checkout strategies used by the various -checkout... methods
/// See git_checkout_strategy_t
typedef NS_OPTIONS(NSInteger, GTCheckoutStrategyType) {
GTCheckoutStrategyNone = GIT_CHECKOUT_NONE,
GTCheckoutStrategySafe = GIT_CHECKOUT_SAFE,
GTCheckoutStrategyForce = GIT_CHECKOUT_FORCE,
GTCheckoutStrategyAllowConflicts = GIT_CHECKOUT_ALLOW_CONFLICTS,
GTCheckoutStrategyRemoveUntracked = GIT_CHECKOUT_REMOVE_UNTRACKED,
GTCheckoutStrategyRemoveIgnored = GIT_CHECKOUT_REMOVE_IGNORED,
GTCheckoutStrategyUpdateOnly = GIT_CHECKOUT_UPDATE_ONLY,
GTCheckoutStrategyDontUpdateIndex = GIT_CHECKOUT_DONT_UPDATE_INDEX,
GTCheckoutStrategyNoRefresh = GIT_CHECKOUT_NO_REFRESH,
GTCheckoutStrategyDisablePathspecMatch = GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH,
GTCheckoutStrategySkipLockedDirectories = GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES,
};

/// Checkout notification flags used by the various -checkout... methods
/// See git_checkout_notify_t
typedef NS_OPTIONS(NSInteger, GTCheckoutNotifyFlags) {
GTCheckoutNotifyNone = GIT_CHECKOUT_NOTIFY_NONE,
GTCheckoutNotifyConflict = GIT_CHECKOUT_NOTIFY_CONFLICT,
GTCheckoutNotifyDirty = GIT_CHECKOUT_NOTIFY_DIRTY,
GTCheckoutNotifyUpdated = GIT_CHECKOUT_NOTIFY_UPDATED,
GTCheckoutNotifyUntracked = GIT_CHECKOUT_NOTIFY_UNTRACKED,
GTCheckoutNotifyIgnored = GIT_CHECKOUT_NOTIFY_IGNORED,

GTCheckoutNotifyAll = GIT_CHECKOUT_NOTIFY_ALL,
};
@class GTCheckoutOptions;

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

/// A `GTCheckoutOptions` object describing how to perform the checkout.
extern NSString * const GTRepositoryCloneCheckoutOptions;

/// A `GTCredentialProvider`, that will be used to authenticate against the
/// remote.
extern NSString * const GTRepositoryCloneOptionsCredentialProvider;
Expand Down Expand Up @@ -199,7 +174,7 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
/// options - A dictionary consisting of the options:
/// `GTRepositoryCloneOptionsTransportFlags`,
/// `GTRepositoryCloneOptionsBare`,
/// `GTRepositoryCloneOptionsCheckout`,
/// `GTRepositoryCloneCheckoutOptions`,
/// `GTRepositoryCloneOptionsCredentialProvider`,
/// `GTRepositoryCloneOptionsCloneLocal`,
/// `GTRepositoryCloneOptionsServerCertificateURL`
Expand All @@ -209,6 +184,9 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
/// (if `GTRepositoryCloneOptionsCheckout` is YES).
///
/// returns nil (and fills the error parameter) if an error occurred, or a GTRepository object if successful.
+ (id)cloneFromURL:(NSURL *)originURL toWorkingDirectory:(NSURL *)workdirURL options:(NSDictionary *)options error:(NSError **)error transferProgressBlock:(void (^)(const git_transfer_progress *, BOOL *stop))transferProgressBlock;

/// Backward-compatible method that uses `GTRepositoryCloneOptionsCheckout`
+ (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;

/// Lookup objects in the repo by oid or sha1
Expand Down Expand Up @@ -454,7 +432,7 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
/// progressBlock - The block to call back for progress updates. Can be nil.
///
/// Returns YES if operation was successful, NO otherwise
- (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;
- (BOOL)checkoutCommit:(GTCommit *)targetCommit options:(GTCheckoutOptions *)options error:(NSError **)error;

/// Checkout a reference
///
Expand All @@ -467,13 +445,13 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
/// progressBlock - The block to call back for progress updates. Can be nil.
///
/// Returns YES if operation was successful, NO otherwise
- (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;
- (BOOL)checkoutReference:(GTReference *)targetReference options:(GTCheckoutOptions *)options error:(NSError **)error;

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

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

/// Flush the gitattributes cache.
- (void)flushAttributesCache;
Expand Down
Loading

0 comments on commit de9f512

Please sign in to comment.