Skip to content

Commit d9cdb5d

Browse files
committed
Merge pull request #418 from libgit2/repository-init-options
Extend repository initialization with options
2 parents ec53c3e + 083fd81 commit d9cdb5d

File tree

5 files changed

+98
-35
lines changed

5 files changed

+98
-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 GTRepositoryInitOptionsWorkingDirectoryPath;
134+
135+
/// An `NSString` of the Git description to use for the new repository.
136+
extern NSString * const GTRepositoryInitOptionsDescription;
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 GTRepositoryInitOptionsTemplateURL;
141+
142+
/// An `NSString` of the name to use for the initial `HEAD` reference.
143+
extern NSString * const GTRepositoryInitOptionsInitialHEAD;
144+
145+
/// An `NSString` representing an origin URL to add to the repository after
146+
/// initialization.
147+
extern NSString * const GTRepositoryInitOptionsOriginURLString;
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 `GTRepositoryInitOptions…` keys controlling how
172+
/// the 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: 30 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 GTRepositoryInitOptionsWorkingDirectoryPath = @"GTRepositoryInitOptionsWorkingDirectoryPath";
65+
NSString * const GTRepositoryInitOptionsDescription = @"GTRepositoryInitOptionsDescription";
66+
NSString * const GTRepositoryInitOptionsTemplateURL = @"GTRepositoryInitOptionsTemplateURL";
67+
NSString * const GTRepositoryInitOptionsInitialHEAD = @"GTRepositoryInitOptionsInitialHEAD";
68+
NSString * const GTRepositoryInitOptionsOriginURLString = @"GTRepositoryInitOptionsOriginURLString";
6269

6370
typedef void (^GTRepositorySubmoduleEnumerationBlock)(GTSubmodule *submodule, NSError *error, BOOL *stop);
6471
typedef void (^GTRepositoryTagEnumerationBlock)(GTTag *tag, BOOL *stop);
@@ -114,19 +121,28 @@ + (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.mode = (uint32_t)
132+
[optionsDict[GTRepositoryInitOptionsMode] unsignedIntegerValue];
133+
options.workdir_path = [optionsDict[GTRepositoryInitOptionsWorkingDirectoryPath] UTF8String];
134+
options.description = [optionsDict[GTRepositoryInitOptionsDescription] UTF8String];
135+
options.template_path = [optionsDict[GTRepositoryInitOptionsTemplateURL] path].UTF8String;
136+
options.initial_head = [optionsDict[GTRepositoryInitOptionsInitialHEAD] UTF8String];
137+
options.origin_url = [optionsDict[GTRepositoryInitOptionsOriginURLString] UTF8String];
138+
139+
// This default mirrors git_repository_init().
140+
NSNumber *flags = optionsDict[GTRepositoryInitOptionsFlags];
141+
options.flags = (flags == nil ? GIT_REPOSITORY_INIT_MKPATH : (uint32_t)flags.unsignedIntegerValue);
142+
127143
const char *path = localFileURL.path.fileSystemRepresentation;
128144
git_repository *repository = NULL;
129-
int gitError = git_repository_init(&repository, path, bare);
145+
int gitError = git_repository_init_ext(&repository, path, &options);
130146
if (gitError != GIT_OK || repository == NULL) {
131147
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Failed to initialize empty repository at URL %@.", localFileURL];
132148
return nil;
@@ -194,10 +210,10 @@ static int remoteCreate(git_remote **remote, git_repository *repo, const char *n
194210
int error;
195211
struct GTRemoteCreatePayload *pld = payload;
196212
git_remote_callbacks *callbacks = &pld->remoteCallbacks;
197-
213+
198214
if ((error = git_remote_create(remote, repo, name, url)) < 0)
199215
return error;
200-
216+
201217
return git_remote_set_callbacks(*remote, callbacks);
202218
}
203219

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

242258
struct GTRemoteCreatePayload remoteCreatePayload;
243259
remoteCreatePayload.remoteCallbacks = cloneOptions.remote_callbacks;
244-
260+
245261
cloneOptions.remote_cb = remoteCreate;
246262
cloneOptions.remote_cb_payload = &remoteCreatePayload;
247263

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: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,26 @@
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+
NSError *error;
29+
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:newRepoURL options:nil error:&error];
2930
expect(repository).notTo(beNil());
31+
expect(error).to(beNil());
32+
3033
expect(repository.gitDirectoryURL).notTo(beNil());
3134
expect(@(repository.bare)).to(beFalsy());
3235
});
3336

3437
it(@"should initialize a bare repository", ^{
3538
NSURL *newRepoURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"init-repo.git"];
39+
NSDictionary *options = @{
40+
GTRepositoryInitOptionsFlags: @(GTRepositoryInitBare | GTRepositoryInitCreatingRepositoryDirectory)
41+
};
3642

37-
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:newRepoURL bare:YES error:NULL];
43+
NSError *error;
44+
GTRepository *repository = [GTRepository initializeEmptyRepositoryAtFileURL:newRepoURL options:options error:&error];
3845
expect(repository).notTo(beNil());
46+
expect(error).to(beNil());
47+
3948
expect(repository.gitDirectoryURL).notTo(beNil());
4049
expect(@(repository.bare)).to(beTruthy());
4150
});
@@ -199,7 +208,8 @@
199208
it(@"should return YES for a new repository", ^{
200209
NSError *error = nil;
201210
NSURL *fileURL = [self.tempDirectoryFileURL URLByAppendingPathComponent:@"newrepo"];
202-
GTRepository *newRepo = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL error:&error];
211+
GTRepository *newRepo = [GTRepository initializeEmptyRepositoryAtFileURL:fileURL options:nil error:&error];
212+
expect(newRepo).notTo(beNil());
203213
expect(@(newRepo.isEmpty)).to(beTruthy());
204214
[NSFileManager.defaultManager removeItemAtURL:fileURL error:NULL];
205215
});

ObjectiveGitTests/QuickSpec+GTFixtures.m

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,18 @@ - (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"];
152+
NSDictionary *options = @{
153+
GTRepositoryInitOptionsFlags: @(GTRepositoryInitBare | GTRepositoryInitCreatingRepositoryDirectory)
154+
};
152155

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

0 commit comments

Comments
 (0)