Skip to content

Instantly share code, notes, and snippets.

@pietbrauer
Created June 17, 2015 20:05
Show Gist options
  • Save pietbrauer/b1b3d2c6bd927ac85094 to your computer and use it in GitHub Desktop.
Save pietbrauer/b1b3d2c6bd927ac85094 to your computer and use it in GitHub Desktop.
- (void)pull:(GTRemote *)remote completion:(void (^)())completion failure:(void (^)(NSError *error))failure {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *fetchError;
[self fetchRemote:remote withOptions:nil error:&fetchError progress:nil];
if (fetchError) {
if (failure) {
failure(fetchError);
}
return;
}
// Get the remote branch
GTBranch *remoteBranch = [self remoteBranchesWithError:nil].firstObject;
NSError *mergeError = [self mergeBranch:remoteBranch];
if (mergeError) {
if (failure) {
failure(mergeError);
}
}
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion();
}
});
});
}
- (NSError *)mergeBranch:(GTBranch *)remoteBranch {
// Get the local branch
GTBranch *localBranch = [self localBranchesWithError:nil].firstObject;
// Get the local & remote commit
GTCommit *localCommit = [localBranch targetCommitAndReturnError:nil];
GTCommit *remoteCommit = [remoteBranch targetCommitAndReturnError:nil];
// Get the trees of both
GTTree *localTree = localCommit.tree;
GTTree *remoteTree = remoteCommit.tree;
// Get OIDs of both commits too
GTOID *localOID = localCommit.OID;
GTOID *remoteOID = remoteCommit.OID;
// Find a merge base to act as the ancestor between these two commits
NSError *ancestorError;
GTCommit *ancestor = [self mergeBaseBetweenFirstOID:localOID secondOID:remoteOID error:&ancestorError];
if (ancestorError) {
return ancestorError;
}
// Get the ancestors tree
GTTree *ancestorTree = ancestor.tree;
// Merge into the local tree
NSError *mergedIndexError;
GTIndex *mergedIndex = [localTree merge:remoteTree ancestor:ancestorTree error:&mergedIndexError];
if (mergedIndexError) {
return mergedIndexError;
}
// Write the merge to disk and store the new tree
NSError *writeError;
GTTree *tree = [mergedIndex writeTreeToRepository:self error:&writeError];
if (writeError) {
return writeError;
}
if (tree.entryCount > 0) {
NSError *commitError;
GTCommit *commit = [self createCommitWithTree:tree
message:remoteCommit.message
author:remoteCommit.author
committer:remoteCommit.committer
parents:@[localCommit]
updatingReferenceNamed:localBranch.reference.name
error:&commitError];
if (commitError) {
return commitError;
}
NSLog(@"merge commit %@", commit.SHA);
}
return nil;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment