diff --git a/PBGitRepository.h b/PBGitRepository.h index ac57508..ffa9eb7 100644 --- a/PBGitRepository.h +++ b/PBGitRepository.h @@ -31,6 +31,7 @@ extern NSString* PBGitRepositoryErrorDomain; - (BOOL) checkoutRefish:(id )ref; - (BOOL) checkoutFiles:(NSArray *)files fromRefish:(id )ref; +- (BOOL) mergeWithRefish:(id )ref; - (BOOL) createBranch:(NSString *)branchName atRefish:(id )ref; - (BOOL) createTag:(NSString *)tagName message:(NSString *)message atRefish:(id )commitSHA; - (BOOL) deleteRef:(PBGitRef *)ref; diff --git a/PBGitRepository.m b/PBGitRepository.m index 87935d9..69c274c 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -474,6 +474,26 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; return YES; } + +- (BOOL) mergeWithRefish:(id )ref +{ + NSString *refName = [ref refishName]; + + int retValue = 1; + NSArray *arguments = [NSArray arrayWithObjects:@"merge", refName, nil]; + NSString *output = [self outputInWorkdirForArguments:arguments retValue:&retValue]; + if (retValue) { + NSString *headName = [[[self headRef] ref] shortName]; + NSString *message = [NSString stringWithFormat:@"There was an error merging %@ into %@.", refName, headName]; + [self.windowController showErrorSheetTitle:@"Merge failed!" message:message arguments:arguments output:output]; + return NO; + } + + [self reloadRefs]; + [self readCurrentBranch]; + return YES; +} + - (BOOL) createBranch:(NSString *)branchName atRefish:(id )ref { if (!branchName || !ref) diff --git a/PBRefController.h b/PBRefController.h index 3aac522..902d50d 100644 --- a/PBRefController.h +++ b/PBRefController.h @@ -24,6 +24,7 @@ } - (void) checkout:(PBRefMenuItem *)sender; +- (void) merge:(PBRefMenuItem *)sender; - (void) createBranch:(PBRefMenuItem *)sender; - (void) copySHA:(PBRefMenuItem *)sender; - (void) copyPatch:(PBRefMenuItem *)sender; diff --git a/PBRefController.m b/PBRefController.m index 6b25b39..e888745 100644 --- a/PBRefController.m +++ b/PBRefController.m @@ -39,6 +39,15 @@ } +#pragma mark Merge + +- (void) merge:(PBRefMenuItem *)sender +{ + id refish = [sender refish]; + [historyController.repository mergeWithRefish:refish]; +} + + #pragma mark Checkout - (void) checkout:(PBRefMenuItem *)sender diff --git a/PBRefMenuItem.m b/PBRefMenuItem.m index dc9e29a..ab87576 100644 --- a/PBRefMenuItem.m +++ b/PBRefMenuItem.m @@ -39,8 +39,11 @@ NSMutableArray *items = [NSMutableArray array]; NSString *targetRefName = [ref shortName]; + PBGitCommit *commit = [repo commitForRef:ref]; + BOOL isOnHeadBranch = [commit isOnHeadBranch]; PBGitRef *headRef = [[repo headRef] ref]; + NSString *headRefName = [headRef shortName]; BOOL isHead = [ref isEqualToRef:headRef]; // checkout ref @@ -57,6 +60,11 @@ // view tag info if ([ref isTag]) [items addObject:[PBRefMenuItem itemWithTitle:@"View tag info…" action:@selector(showTagInfoSheet:) enabled:YES]]; + [items addObject:[PBRefMenuItem separatorItem]]; + + // merge ref + NSString *mergeTitle = isOnHeadBranch ? @"Merge" : [NSString stringWithFormat:@"Merge %@ into %@", targetRefName, headRefName]; + [items addObject:[PBRefMenuItem itemWithTitle:mergeTitle action:@selector(merge:) enabled:!isOnHeadBranch]]; // delete ref [items addObject:[PBRefMenuItem separatorItem]]; @@ -76,6 +84,9 @@ { NSMutableArray *items = [NSMutableArray array]; + NSString *headBranchName = [[[commit.repository headRef] ref] shortName]; + BOOL isOnHeadBranch = [commit isOnHeadBranch]; + [items addObject:[PBRefMenuItem itemWithTitle:@"Checkout Commit" action:@selector(checkout:) enabled:YES]]; [items addObject:[PBRefMenuItem separatorItem]]; @@ -85,6 +96,11 @@ [items addObject:[PBRefMenuItem itemWithTitle:@"Copy SHA" action:@selector(copySHA:) enabled:YES]]; [items addObject:[PBRefMenuItem itemWithTitle:@"Copy Patch" action:@selector(copyPatch:) enabled:YES]]; + [items addObject:[PBRefMenuItem separatorItem]]; + + // merge commit + NSString *mergeTitle = isOnHeadBranch ? @"Merge commit" : [NSString stringWithFormat:@"Merge commit into %@", headBranchName]; + [items addObject:[PBRefMenuItem itemWithTitle:mergeTitle action:@selector(merge:) enabled:!isOnHeadBranch]]; for (PBRefMenuItem *item in items) { [item setTarget:target];