-
Notifications
You must be signed in to change notification settings - Fork 281
Fetch support. #224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fetch support. #224
Changes from 1 commit
132f488
9683b82
8ddbf4d
e219d96
25ac41d
69a6870
32e16dd
32d431c
b1e068c
9ae2de9
99fd4f8
9147337
fe0fcd4
f1e0fed
1f4a741
b66841d
b78b7a7
132d34b
085bfcd
53e72ac
9b24687
016e600
326c2a1
3e3741d
dbeb1c7
951f2d3
2a52a5a
df7797b
6a5962e
2da274b
264e432
315c7fc
82ef2b4
e9eb978
6ec740c
d8f467c
48cb468
30466af
95b4397
1be6929
36b83c0
7dce701
df9e8f7
0ca55db
89435cd
958de2c
c0cddf8
7e8d9c1
e5c6f1e
8be93a4
95be58a
921b3cf
4c8b62e
cb4a418
358c700
69073fd
da4acdd
3597084
8000
3820fbd
d04f203
3b46ae3
e94e011
a14aaea
46f73ae
fcaee88
d31823d
e38111a
01fbe83
a2c219c
055425d
6422662
8385bca
9051caf
7944375
c18ad46
300422f
ed50421
2561348
36dc5f4
f82ac62
321d1a3
f7a63f5
aa41ad5
6ac1d81
ee4a798
564e3b3
dff9ece
393d9b6
9e656fc
b00bd04
f550b23
dbe3571
a8939d3
b2aa3c1
fe64125
749bae7
bb31e14
f7e65e5
34ba3fc
2b1b414
4ff2704
545424d
6ae8d4c
0416a80
fe53e2b
5154b01
9721263
ee395c1
8eccf6d
073dc08
6389d67
d9ddd3b
1070b18
cf17a4b
1510cea
401bf3d
7f223a9
defc906
6f48fe8
e4d9317
9861940
aa67fc5
f36fc31
f35af60
503fe77
64c09d6
b27d70c
c4da29f
8fb43d7
c033c41
66825b7
a425175
6a2eb3e
ffbcc17
9f408ac
f51b848
2f8160c
d3f4cca
5f0b899
3b739da
e5f1bb4
f934b16
37107c8
06295d3
47706f5
5533868
7b7f600
b9b0594
2593ebb
f3e1380
fc766f4
e79a88a
fc6efba
741a444
5ed28b8
0489bd8
5f363f7
4c00640
b2887f7
6385b01
60de3e3
f01278a
7160ff1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,20 @@ | |
#import "git2.h" | ||
|
||
@class GTRepository; | ||
@class GTOID; | ||
@class GTReference; | ||
|
||
typedef enum { | ||
GTCredentialTypeUserPassPlaintext = GIT_CREDTYPE_USERPASS_PLAINTEXT, | ||
GTCredentialTypeSSHKeyFilePassPhrase = GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE, | ||
GTCredentialTypeSSHPublicKey = GIT_CREDTYPE_SSH_PUBLICKEY, | ||
} GTCredentialType; | ||
|
||
typedef enum { | ||
GTRemoteCompletionTypeDownload = GIT_REMOTE_COMPLETION_DOWNLOAD, | ||
GTRemoteCompletionTypeIndexing = GIT_REMOTE_COMPLETION_INDEXING, | ||
GTRemoteCompletionTypeError = GIT_REMOTE_COMPLETION_ERROR, | ||
} GTRemoteCompletionType; | ||
|
||
@interface GTRemote : NSObject | ||
|
||
|
@@ -24,4 +38,6 @@ | |
// The underlying `git_remote` object. | ||
- (git_remote *)git_remote __attribute__((objc_returns_inner_pointer)); | ||
|
||
- (BOOL)fetchWithError:(NSError **)error credentials:(int (^)(git_cred **cred, GTCredentialType allowedTypes, NSURL *url))credBlock progress:(void (^)(NSString *message, int length))progressBlock completion:(int (^)(GTRemoteCompletionType type))completionBlock updateTips:(int (^)(GTReference *ref, GTOID *a, GTOID *b))updateTipsBlock; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's this first callback for? Also, is there any way to break this method down so it doesn't need to accept so many blocks at once? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's for getting credentials to set up the underlying transport (needed for things like accessing GitHub repositories, or password-protected ones). Yeah, I plan to do that (as I did in #223), but I'm first fiddling with the "main" method, because I'm not sure I got it right and I don't want to have to rewrite 3 declarations on each change. |
||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -82,45 +82,84 @@ - (NSString *)URLString { | |
return @(URLString); | ||
} | ||
|
||
static int fetch_cred_acquire_cb(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *payload) { | ||
GTRemote *myself = (__bridge GTRemote *)payload; | ||
NSLog(@"fetch_cred_acquire_cb: %@: url: %s, username: %s, types: %d", myself, url, username_from_url, allowed_types); | ||
switch (allowed_types) { | ||
case GIT_CREDTYPE_USERPASS_PLAINTEXT: | ||
break; | ||
case GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE: | ||
break; | ||
case GIT_CREDTYPE_SSH_PUBLICKEY: | ||
break; | ||
#pragma mark Fetch | ||
|
||
typedef int (^GTCredentialAcquireBlock)(git_cred **cred, GTCredentialType allowedTypes, NSURL *url); | ||
|
||
typedef void (^GTRemoteFetchProgressBlock)(NSString *message, int length); | ||
|
||
typedef int (^GTRemoteFetchCompletionBlock)(GTRemoteCompletionType type); | ||
|
||
typedef int (^GTRemoteFetchUpdateTipsBlock)(GTReference *ref, GTOID *a, GTOID *b); | ||
|
||
typedef struct { | ||
__unsafe_unretained GTRemote *myself; | ||
__unsafe_unretained GTCredentialAcquireBlock credBlock; | ||
__unsafe_unretained GTRemoteFetchProgressBlock progressBlock; | ||
__unsafe_unretained GTRemoteFetchCompletionBlock completionBlock; | ||
__unsafe_unretained GTRemoteFetchUpdateTipsBlock updateTipsBlock; | ||
} GTRemoteFetchInfo; | ||
|
||
static int fetch_cred_acquire_cb(git_cred **cred, const char *urlStr, const char *username_from_url, unsigned int allowed_types, void *payload) { | ||
GTRemoteFetchInfo *info = (GTRemoteFetchInfo *)payload; | ||
|
||
if (info->credBlock == nil) { | ||
NSString *errorMsg = [NSString stringWithFormat:@"No credential block passed, but authentication was requested for remote %@", info->myself.name]; | ||
giterr_set_str(GIT_EUSER, errorMsg.UTF8String); | ||
return GIT_ERROR; | ||
} | ||
return GIT_OK; | ||
|
||
NSURL *url = [NSURL URLWithString:@(urlStr)]; | ||
NSCAssert(url != nil, @"Failed to convert %s to an URL", urlStr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't be an assertion, and we probably shouldn't even be using |
||
|
||
return info->credBlock(cred, (GTCredentialType)allowed_types, url); | ||
} | ||
|
||
static void fetch_progress(const char *str, int len, void *data) { | ||
GTRemote *myself = (__bridge GTRemote *)data; | ||
NSLog(@"fetch_progress: %@: str: %s, len: %d", myself, str, len); | ||
static void fetch_progress(const char *str, int len, void *payload) { | ||
GTRemoteFetchInfo *info = (GTRemoteFetchInfo *)payload; | ||
|
||
if (info->progressBlock == nil) return; | ||
|
||
info->progressBlock(@(str), len); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are these arguments? |
||
} | ||
|
||
static int fetch_completion(git_remote_completion_type type, void *data) { | ||
GTRemote *myself = (__bridge GTRemote *)data; | ||
NSLog(@"fetch_completion: %@: %d", myself, type); | ||
return GIT_OK; | ||
static int fetch_completion(git_remote_completion_type type, void *payload) { | ||
GTRemoteFetchInfo *info = (GTRemoteFetchInfo *)payload; | ||
|
||
if (info->completionBlock == nil) return GIT_OK; | ||
|
||
return info->completionBlock((GTRemoteCompletionType)type); | ||
} | ||
|
||
static int fetch_update_tips(const char *refname, const git_oid *a, const git_oid *b, void *data) { | ||
GTRemote *myself = (__bridge GTRemote *)data; | ||
static int fetch_update_tips(const char *refname, const git_oid *a, const git_oid *b, void *payload) { | ||
GTRemoteFetchInfo *info = (GTRemoteFetchInfo *)payload; | ||
if (info->updateTipsBlock == nil) return GIT_OK; | ||
|
||
NSError *error = nil; | ||
GTReference *ref = [GTReference referenceByLookingUpReferencedNamed:@(refname) inRepository:info->myself.repository error:&error]; | ||
if (ref == nil) { | ||
NSLog(@"Error resolving reference %s: %@", refname, error); | ||
} | ||
|
||
GTOID *oid_a = [[GTOID alloc] initWithGitOid:a]; | ||
GTOID *oid_b = [[GTOID alloc] initWithGitOid:b]; | ||
NSLog(@"fetch_update_tips: %@: refname: %s, OID a: %@, b: %@", myself, refname, oid_a, oid_b); | ||
return GIT_OK; | ||
return info->updateTipsBlock(ref, oid_a, oid_b); | ||
} | ||
|
||
- (BOOL)fetchWithError:(NSError **)error { | ||
- (BOOL)fetchWithError:(NSError **)error credentials:(GTCredentialAcquireBlock)credBlock progress:(GTRemoteFetchProgressBlock)progressBlock completion:(GTRemoteFetchCompletionBlock)completionBlock updateTips:(GTRemoteFetchUpdateTipsBlock)updateTipsBlock { | ||
GTRemoteFetchInfo payload = { | ||
.myself = self, | ||
.credBlock = credBlock, | ||
.progressBlock = progressBlock, | ||
.completionBlock = completionBlock, | ||
.updateTipsBlock = updateTipsBlock, | ||
}; | ||
|
||
git_remote_callbacks remote_callbacks = GIT_REMOTE_CALLBACKS_INIT; | ||
remote_callbacks.progress = fetch_progress; | ||
remote_callbacks.completion = fetch_completion; | ||
remote_callbacks.update_tips = fetch_update_tips; | ||
remote_callbacks.payload = (__bridge void *)(self); | ||
remote_callbacks.payload = &payload; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should make sure to unset these callbacks after we're done, so there's no possibility of accessing a deallocated |
||
|
||
int gitError = git_remote_set_callbacks(self.git_remote, &remote_callbacks); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's really unfortunate that these functions aren't thread-safe, but, since they're not, we should synchronize on the remote or the repository to avoid other threads interfering. |
||
if (gitError != GIT_OK) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you document these enums?