Skip to content

Commit b1c0d3a

Browse files
committed
Extend repository initialization with options
1 parent ec53c3e commit b1c0d3a

File tree

5 files changed

+85
-35
lines changed

5 files changed

+85
-35
lines changed

ObjectiveGit/GTRepository.h

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#import "GTReference.h"
3636
#import "GTFilterList.h"
3737
#import "git2/checkout.h"
38+
#import "git2/repository.h"
3839
#import "git2/transport.h"
3940
#import "git2/sys/transport.h"
4041

@@ -88,22 +89,62 @@ typedef NS_OPTIONS(NSInteger, GTTransportFlags) {
8889

8990
/// An `NSNumber` wrapped `GTTransportFlags`, documented above.
9091
/// Default value is `GTTransportFlagsNone`.
91-
extern NSString *const GTRepositoryCloneOptionsTransportFlags;
92+
extern NSString * const GTRepositoryCloneOptionsTransportFlags;
9293

9394
/// An `NSNumber` wrapped `BOOL`, if YES, create a bare clone.
9495
/// Default value is `NO`.
95-
extern NSString *const GTRepositoryCloneOptionsBare;
96+
extern NSString * const GTRepositoryCloneOptionsBare;
9697

9798
/// An `NSNumber` wrapped `BOOL`, if NO, don't checkout the remote HEAD.
9899
/// Default value is `YES`.
99-
extern NSString *const GTRepositoryCloneOptionsCheckout;
100+
extern NSString * const GTRepositoryCloneOptionsCheckout;
100101

101102
/// A `GTCredentialProvider`, that will be used to authenticate against the
102103
/// remote.
103-
extern NSString *const GTRepositoryCloneOptionsCredentialProvider;
104+
extern NSString * const GTRepositoryCloneOptionsCredentialProvider;
104105

105106
/// A BOOL indicating whether local clones should actually clone, or just link.
106-
extern NSString *const GTRepositoryCloneOptionsCloneLocal;
107+
extern NSString * const GTRepositoryCloneOptionsCloneLocal;
108+
109+
/// Initialization flags associated with `GTRepositoryInitOptionsFlags` for
110+
/// +initializeEmptyRepositoryAtFileURL:options:error:.
111+
///
112+
/// See `git_repository_init_flag_t` for more information.
113+
typedef NS_OPTIONS(NSInteger, GTRepositoryInitFlags) {
114+
GTRepositoryInitBare = GIT_REPOSITORY_INIT_BARE,
115+
GTRepositoryInitWithoutReinitializing = GIT_REPOSITORY_INIT_NO_REINIT,
116+
GTRepositoryInitWithoutDotGit = GIT_REPOSITORY_INIT_NO_DOTGIT_DIR,
117+
GTRepositoryInitCreatingRepositoryDirectory = GIT_REPOSITORY_INIT_MKDIR,
118+
GTRepositoryInitCreatingIntermediateDirectories = GIT_REPOSITORY_INIT_MKPATH,
119+
GTRepositoryInitWithExternalTemplate = GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE,
120+
GTRepositoryInitWithRelativeGitLink = GIT_REPOSITORY_INIT_RELATIVE_GITLINK,
121+
};
122+
123+
/// An `NSNumber` wrapping `GTRepositoryInitFlags` with which to initialize the
124+
/// repository.
125+
extern NSString * const GTRepositoryInitOptionsFlags;
126+
127+
/// An `NSNumber` wrapping a `mode_t` or `git_repository_init_mode_t` to use
128+
/// for the initialized repository.
129+
extern NSString * const GTRepositoryInitOptionsMode;
130+
131+
/// An `NSString` to the working directory that should be used. If this is a
132+
/// relative path, it will be resolved against the repository path.
133+
extern NSString * const GTRepositoryInitWorkingDirectoryPath;
134+
135+
/// An `NSString` of the Git description to use for the new repository.
136+
extern NSString * const GTRepositoryInitDescription;
137+
138+
/// A file `NSURL` to the template directory that should be used instead of the
139+
/// defaults, if the `GTRepositoryInitWithExternalTemplate` flag is specified.
140+
extern NSString * const GTRepositoryInitTemplateURL;
141+
142+
/// An `NSString` of the name to use for the initial `HEAD` reference.
143+
extern NSString * const GTRepositoryInitInitialHEAD;
144+
145+
/// An `NSString` representing an origin URL to add to the repository after
146+
/// initialization.
147+
extern NSString * const GTRepositoryInitOriginURLString;
107148

108149
@interface GTRepository : NSObject
109150

@@ -127,19 +168,12 @@ extern NSString *const GTRepositoryCloneOptionsCloneLocal;
127168
/// Initializes a new repository at the given file URL.
128169
///
129170
/// fileURL - The file URL for the new repository. Cannot be nil.
171+
/// options - A dictionary of `GTRepositoryInit…` keys controlling how the
172+
/// repository is initialized, or nil to use the defaults.
130173
/// error - The error if one occurs.
131174
///
132175
/// Returns the initialized repository, or nil if an error occurred.
133-
+ (instancetype)initializeEmptyRepositoryAtFileURL:(NSURL *)fileURL error:(NSError **)error;
134-
135-
/// Initializes a new repository at the given file URL.
136-
///
137-
/// fileURL - The file URL for the new repository. Cannot be nil.
138-
/// error - The error if one occurs.
139-
/// bare - Should the repository be created bare?
140-
///
141-
/// Returns the initialized repository, or nil if an error occurred.
142-
+ (instancetype)initializeEmptyRepositoryAtFileURL:(NSURL *)fileURL bare:(BOOL)bare error:(NSError **)error;
176+
+ (instancetype)initializeEmptyRepositoryAtFileURL:(NSURL *)fileURL options:(NSDictionary *)options error:(NSError **)error;
143177

144178
+ (id)repositoryWithURL:(NSURL *)localFileURL error:(NSError **)error;
145179
- (id)initWithURL:(NSURL *)localFileURL error:(NSError **)error;

ObjectiveGit/GTRepository.m

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,18 @@
5454

5555
#import "git2.h"
5656

57-
NSString *const GTRepositoryCloneOptionsBare = @"GTRepositoryCloneOptionsBare";
58-
NSString *const GTRepositoryCloneOptionsCheckout = @"GTRepositoryCloneOptionsCheckout";
59-
NSString *const GTRepositoryCloneOptionsTransportFlags = @"GTRepositoryCloneOptionsTransportFlags";
60-
NSString *const GTRepositoryCloneOptionsCredentialProvider = @"GTRepositoryCloneOptionsCredentialProvider";
61-
NSString *const GTRepositoryCloneOptionsCloneLocal = @"GTRepositoryCloneOptionsCloneLocal";
57+
NSString * const GTRepositoryCloneOptionsBare = @"GTRepositoryCloneOptionsBare";
58+
NSString * const GTRepositoryCloneOptionsCheckout = @"GTRepositoryCloneOptionsCheckout";
59+
NSString * const GTRepositoryCloneOptionsTransportFlags = @"GTRepositoryCloneOptionsTransportFlags";
60+
NSString * const GTRepositoryCloneOptionsCredentialProvider = @"GTRepositoryCloneOptionsCredentialProvider";
61+
NSString * const GTRepositoryCloneOptionsCloneLocal = @"GTRepositoryCloneOptionsCloneLocal";
62+
NSString * const GTRepositoryInitOptionsFlags = @"GTRepositoryInitOptionsFlags";
63+
NSString * const GTRepositoryInitOptionsMode = @"GTRepositoryInitOptionsMode";
64+
NSString * const GTRepositoryInitWorkingDirectoryPath = @"GTRepositoryInitWorkingDirectoryPath";
65+
NSString * const GTRepositoryInitDescription = @"GTRepositoryInitDescription";
66+
NSString * const GTRepositoryInitTemplateURL = @"GTRepositoryInitTemplateURL";
67+
NSString * const GTRepositoryInitInitialHEAD = @"GTRepositoryInitInitialHEAD";
68+
NSString * const GTRepositoryInitOriginURLString = @"GTRepositoryInitOriginURLString";
6269

6370
typedef void (^GTRepositorySubmoduleEnumerationBlock)(GTSubmodule *submodule, NSError *error, BOOL *stop);
6471
typedef void (^GTRepositoryTagEnumerationBlock)(GTTag *tag, BOOL *stop);
@@ -114,19 +121,25 @@ + (BOOL)isAGitDirectory:(NSURL *)directory {
114121
return NO;
115122
}
116123

117-
+ (instancetype)initializeEmptyRepositoryAtFileURL:(NSURL *)localFileURL error:(NSError **)error {
118-
return [self initializeEmptyRepositoryAtFileURL:localFileURL bare:NO error:error];
119-
}
120-
121-
+ (instancetype)initializeEmptyRepositoryAtFileURL:(NSURL *)localFileURL bare:(BOOL)bare error:(NSError **)error {
124+
+ (instancetype)initializeEmptyRepositoryAtFileURL:(NSURL *)localFileURL options:(NSDictionary *)optionsDict error:(NSError **)error {
122125
if (!localFileURL.isFileURL || localFileURL.path == nil) {
123126
if (error != NULL) *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileWriteUnsupportedSchemeError userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(@"Invalid file path URL to initialize repository.", @"") }];
124127
return nil;
125128
}
126129

130+
git_repository_init_options options = GIT_REPOSITORY_INIT_OPTIONS_INIT;
131+
options.flags = (uint32_t)[optionsDict[GTRepositoryInitOptionsFlags] unsignedIntegerValue];
132+
options.mode = (uint32_t)
133+
[optionsDict[GTRepositoryInitOptionsMode] unsignedIntegerValue];
134+
options.workdir_path = [optionsDict[GTRepositoryInitWorkingDirectoryPath] UTF8String];
135+
options.description = [optionsDict[GTRepositoryInitDescription] UTF8String];
136+
options.template_path = [optionsDict[GTRepositoryInitTemplateURL] path].UTF8String;
137+
options.initial_head = [optionsDict[GTRepositoryInitInitialHEAD] UTF8String];
138+
options.origin_url = [optionsDict[GTRepositoryInitOriginURLString] UTF8String];
139+
127140
const char *path = localFileURL.path.fileSystemRepresentation;
128141
git_repository *repository = NULL;
129-
int gitError = git_repository_init(&repository, path, bare);
142+
int gitError = git_repository_init_ext(&repository, path, &options);
130143
if (gitError != GIT_OK || repository == NULL) {
131144
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Failed to initialize empty repository at URL %@.", localFileURL];
132145
return nil;
@@ -194,10 +207,10 @@ static int remoteCreate(git_remote **remote, git_repository *repo, const char *n
194207
int error;
195208
struct GTRemoteCreatePayload *pld = payload;
196209
git_remote_callbacks *callbacks = &pld->remoteCallbacks;
197-
210+
198211
if ((error = git_remote_create(remote, repo, name, url)) < 0)
199212
return error;
200-
213+
201214
return git_remote_set_callbacks(*remote, callbacks);
202215
}
203216

@@ -241,7 +254,7 @@ + (id)cloneFromURL:(NSURL *)originURL toWorkingDirectory:(NSURL *)workdirURL opt
241254

242255
struct GTRemoteCreatePayload remoteCreatePayload;
243256
remoteCreatePayload.remoteCallbacks = cloneOptions.remote_callbacks;
244-
257+
245258
cloneOptions.remote_cb = remoteCreate;
246259
cloneOptions.remote_cb_payload = &remoteCreatePayload;
247260

ObjectiveGitTests/GTRepositoryCommittingSpec.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
CFRelease(UUIDRef);
2323

2424
NSURL *fileURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:UUID isDirectory:NO];
25-
repository = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL error:NULL];
25+
repository = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL options:nil error:NULL];
2626
expect(repository).notTo(beNil());
2727
});
2828

ObjectiveGitTests/GTRepositorySpec.m

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,19 @@
2525
it(@"should initialize a repository with a working directory by default", ^{
2626
NSURL *newRepoURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"init-repo"];
2727

28-
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:newRepoURL bare:NO error:NULL];
28+
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:newRepoURL options:nil error:NULL];
2929
expect(repository).notTo(beNil());
3030
expect(repository.gitDirectoryURL).notTo(beNil());
3131
expect(@(repository.bare)).to(beFalsy());
3232
});
3333

3434
it(@"should initialize a bare repository", ^{
3535
NSURL *newRepoURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"init-repo.git"];
36+
NSDictionary *options = @{
37+
GTRepositoryInitOptionsFlags: @(GTRepositoryInitBare)
38+
};
3639

37-
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:newRepoURL bare:YES error:NULL];
40+
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:newRepoURL options:options error:NULL];
3841
expect(repository).notTo(beNil());
3942
expect(repository.gitDirectoryURL).notTo(beNil());
4043
expect(@(repository.bare)).to(beTruthy());
@@ -199,7 +202,7 @@
199202
it(@"should return YES for a new repository", ^{
200203
NSError *error = nil;
201204
NSURL *fileURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"newrepo"];
202-
GTRepository *newRepo = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL error:&error];
205+
GTRepository *newRepo = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL options:nil error:&error];
203206
expect(@(newRepo.isEmpty)).to(beTruthy());
204207
[NSFileManager.defaultManager removeItemAtURL:fileURL error:NULL];
205208
});

ObjectiveGitTests/QuickSpec+GTFixtures.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,15 @@ - (GTRepository *)conflictedFixtureRepository {
142142
- (GTRepository *)blankFixtureRepository {
143143
NSURL *repoURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"blank-repo"];
144144

145-
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:repoURL bare:NO error:NULL];
145+
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:repoURL options:nil error:NULL];
146146
XCTAssertNotNil(repository, @"Couldn't create a blank repository");
147147
return repository;
148148
}
149149

150150
- (GTRepository *)blankBareFixtureRepository {
151151
NSURL *repoURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"blank-repo.git"];
152152

153-
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:repoURL bare:YES error:NULL];
153+
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:repoURL options:nil error:NULL];
154154
XCTAssertNotNil(repository, @"Couldn't create a blank repository");
155155
return repository;
156156
}

0 commit comments

Comments
 (0)